Domanda

Da VS 2005, vedo che non è possibile semplicemente creare una dll contro il runtime di MS e distribuirli insieme ( http://www.ddj.com/windows/184406482 ). Sono profondamente confuso da manifest, SxS e co: la documentazione MSDN è davvero scarsa, con riferimenti circolari; specialmente dal momento che sono più un tipo Unix, trovo tutti quelli poco informativi. Il mio problema principale è il collegamento di una DLL con msvc9 o msvc8: dal momento che tali runtime non sono ridistribuibili, quali sono i passaggi per collegare e distribuire tale dll? In particolare, come vengono generati i manifest (non voglio mt.exe, voglio qualcosa che sia portatile tra i compilatori), come vengono incorporati, usati? Che cosa significa montaggio affiancato?

Fondamentalmente, dove posso trovare qualsiasi tipo di specifica al posto del gergo MS?

Grazie a tutti coloro che hanno risposto, questo è stato davvero utile,

È stato utile?

Soluzione

Usiamo un semplice file include in tutte le nostre applicazioni & amp; DLL, vcmanifest.h, quindi imposta tutti i progetti per incorporare il file manifest.

vcmanifest.h

/*----------------------------------------------------------------------------*/

#if _MSC_VER >= 1400

/*----------------------------------------------------------------------------*/

#pragma message ( "Setting up manifest..." )

/*----------------------------------------------------------------------------*/

#ifndef _CRT_ASSEMBLY_VERSION
#include <crtassem.h>
#endif 

/*----------------------------------------------------------------------------*/

#ifdef WIN64
    #pragma message ( "processorArchitecture=amd64" )
    #define MF_PROCESSORARCHITECTURE "amd64"
#else
    #pragma message ( "processorArchitecture=x86" )
    #define MF_PROCESSORARCHITECTURE "x86"
#endif 

/*----------------------------------------------------------------------------*/

#pragma message ( "Microsoft.Windows.Common-Controls=6.0.0.0") 
#pragma comment ( linker,"/manifestdependency:\"type='win32' " \
                  "name='Microsoft.Windows.Common-Controls' " \
                  "version='6.0.0.0' " \
                  "processorArchitecture='" MF_PROCESSORARCHITECTURE "' " \
                  "publicKeyToken='6595b64144ccf1df'\"" )

/*----------------------------------------------------------------------------*/

#ifdef _DEBUG
    #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugCRT=" _CRT_ASSEMBLY_VERSION ) 
    #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
            "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugCRT' "         \
            "version='" _CRT_ASSEMBLY_VERSION "' "                          \
            "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
            "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#else
    #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT=" _CRT_ASSEMBLY_VERSION ) 
    #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
            "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT' "              \
            "version='" _CRT_ASSEMBLY_VERSION "' "                          \
            "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
            "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#endif

/*----------------------------------------------------------------------------*/

#ifdef _MFC_ASSEMBLY_VERSION
    #ifdef _DEBUG
        #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC=" _CRT_ASSEMBLY_VERSION ) 
        #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
                "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC' "              \
                "version='" _MFC_ASSEMBLY_VERSION "' "                          \
                "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
                "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
    #else
        #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC=" _CRT_ASSEMBLY_VERSION ) 
        #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
                "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC' "              \
                "version='" _MFC_ASSEMBLY_VERSION "' "                          \
                "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
                "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
    #endif
#endif /* _MFC_ASSEMBLY_VERSION */

/*----------------------------------------------------------------------------*/

#endif /* _MSC_VER */

/*----------------------------------------------------------------------------*/

Altri suggerimenti

La cosa più semplice da fare: Supponendo un'installazione predefinita di VS2005, avrai un percorso come:

C:\Program Files\Microsoft Visual Studio 8\VC\redist\x86\Microsoft.VC80.CRT

Vai, prendi i file in questa cartella redist e posiziona .manifest AND msvcr80.dll (almeno) nella cartella .exe delle tue applicazioni. Questi file, presenti nella radice della tua installazione, dovrebbero consentire al tuo exe e tutte le DLL collegate contro di loro di funzionare in modo impeccabile senza ricorrere a unire moduli, MSI o qualsiasi tipo di rilevamento just-in-time che il runtime non è installato.

Ecco la voce del blog che spiega il razionale dietro lo SxS decisione crt per VC ++ . Include la spiegazione di quanto sia male collegare staticamente il CRT e perché non dovresti farlo.

Ecco la su come collegare staticamente il crt .

Bene, ho riscontrato alcuni di questi problemi, quindi forse alcuni dei miei commenti saranno utili.

  1. manifest è un file xml. Mentre VS può e ne farà uno per te durante la compilazione, l'altra soluzione è quella di produrre un file di risorse (.rc) e compilarlo in un file di risorse compilato (.res) utilizzando il compilatore di risorse (rc.exe) incluso con VS . Ti consigliamo di eseguire la riga di comando VS dal menu degli strumenti, che farà sì che rc si trovi nel percorso, oltre a impostare correttamente varie variabili ambientali. Quindi compila la tua risorsa. Il file .res risultante può essere utilizzato da altri compilatori.
  2. Assicurati che le dimensioni del tuo file xml manifest siano divisibili per 4. Aggiungi spazio bianco nel mezzo per ottenerlo se necessario. Cerca di evitare di avere caratteri prima del tag xml di apertura o dopo il tag xml di chiusura. A volte ho avuto problemi con questo. Se si esegue il passaggio 2 in modo errato, si aspettano errori di configurazione affiancati. Puoi verificare se questo è il tuo errore aprendo l'exe in un editor di risorse (ad esempio devenv.exe) ed esaminando la risorsa manifest. Puoi anche vedere un esempio di un manifest corretto semplicemente aprendo un file creato, anche se dlls ed exes hanno minuscole differenze nell'ID che dovrebbe essere dato alla risorsa.

Probabilmente vorrai provare su Vista per assicurarti che funzioni correttamente.

Sono ridistribuibili e hai pacchetti ridistribuibili all'interno della directory msvs.

Costruisci con il runtime di tua scelta, aggiungi il pacchetto corrispondente al tuo programma di installazione e non preoccuparti: funzionerà. La differenza è che ora sono installati in un posto diverso (ma è anche lì che la tua app cercherà le librerie).

Altrimenti, MSDN o praticamente qualsiasi libro non troppo vecchio sulla programmazione di Windows c ++.

Grazie per la risposta. Di per sé, posso vedere 3 opzioni, quindi:

  • Uso della direttiva di unione .msi.
  • Uso del pacchetto VS ridistribuibile ed eseguirlo prima del mio programma di installazione
  • Copia dei file ridistribuibili lungo la mia stessa applicazione. Ma in questo caso, come posso fare riferimento ad esso in una gerarchia di filesystem (dire bar / foo1 / foo1.dll e bar / foo2 / foo2.dll fare riferimento a msvcr90.dll in bar /)? Intendo oltre all'ovvio e brutto "copiare la DLL in ogni directory in cui hai la DLL che dipende da essa".

Non è possibile utilizzare VC ++ 8 SP1 / 9 CRT come modulo di unione su Vista e Windows Server 2008 se si dispone di servizi che si desidera avviare o programmi che si desidera eseguire prima di " InstallFinalize " azione nell'MSI.

Questo perché le dll sono installate in WinSXS in " InstallFinalize " azione.

Ma l'MSI "ServiceStart" l'azione viene prima di questo.

Quindi usa un bootstrapper " http://www.davidguyer.us/bmg/ publish.htm "

Oppure cerca di utilizzare il programma di installazione chaing nel programma di installazione 4.5. Ma questo significa che è necessario un bootstrapper per installare 4.5, quindi sembra un po 'inutile ..

Se si intende distribuire i file DLL / .manifest di Microsoft e si utilizza Java JNI, sarà necessario inserirli nella directory bin del proprio JDK / JRE.

Se stai eseguendo l'app in JBoss, dovrai inserirli nella directory JBoss / bin.

È possibile inserire la DLL JNI dove appropriato per l'applicazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top