2013-06-15 11 views
9

Ho cercato di utilizzare l'estensione "Unmanaged Exports" di Robert Giesecke in un progetto di Visual Studio 2010 pro/C#. Tuttavia, non riesco a farlo funzionare - quando controllo la DLL compilata per le esportazioni, il visualizzatore (http://www.nirsoft.net/utils/dll_export_viewer.html) viene sempre visualizzato vuoto, nessuna esportazione sembra essere definita affatto.C# "Esportazioni non gestite"

Ho quasi copiato l'esempio e ho impostato build/config manager/piattaforma attiva su x86. Posso in qualche modo controllare se l'attività MSBuild che esegue tutta la magia sia effettivamente eseguita o meno? Cosa dovrebbe contenere il file di progetto (sembra essere sospettosamente vuoto per me?)

+1

È inoltre possibile utilizzare http://www.dependencywalker.com/ per visualizzare le funzioni esportate. Ho usato l'approccio sopra prima, ma è difficile dire cosa potrebbe andare storto senza ulteriori informazioni. Probabilmente sarà necessario vedere l'intero progetto per eseguire il debug di ciò che sta andando storto. –

risposta

1

Ho utilizzato la versione 1.1.3 e vedo che ora c'è una versione più recente con supporto NuGet. Ho appena fatto un test con questo.

Posso verificare in qualche modo se l'attività MSBuild che esegue tutta la magia è effettivamente eseguita o no?

È possibile ottenere maggiori dettagli da MSBuild dalla riga di comando o regolare la verbosità che le richieste di Visual Studio: Tools > Options > Project and Solutions > Build and Run > MSBuild project build output verbosity [VS 2010]. Probabilmente vorrai ripristinarlo non appena avrai risolto i problemi.

Ho visto l'obiettivo e l'attività sono state chiamate ma non ho visto alcun risultato finché non ho passato la piattaforma del progetto a x86. Poi vedo varie voci, relativi log, compresi Adding .vtentry:0 .export ....

Quale dovrebbe essere il file di progetto contengono (sembra di essere sospetto vuoto per me?)

non c'è molto bisogno in il file di progetto. NuGet fa tutto: un riferimento all'assembly DllExport e un inclusivo per il file di destinazione.

Un paio di cose che mi vengono in mente che potrebbe si essere inciampare:

  1. Assicurarsi di essere in realtà la costruzione del progetto. Il Solution Build Manager può avere alcuni progetti non impostati per la configurazione della soluzione selezionata.
  2. Assicurarsi di controllare la DLL corretta. L'attività di compilazione scrive il percorso nel log di compilazione. La linea inizia con Assembling.
+0

stava lottando per ore ... E il tuo citato ** punto # 2 era la risoluzione! Ci sono così tante cartelle di output di VS che contengono un file '* .dll' costruito, ma non funzionavano tutte (non stavano esportando le funzioni), solo quello in' .. \ ClassLibrary1 \ bin \ x86 \ Debug' lo ha fatto. Probabilmente l'errore di un principiante, ma Grazie: D –

19

Raccomanderei di farlo in modo documentato invece di affidarsi a un hack non documentato di un autore che non fornisce supporto. Facciamo un esempio:

namespace Publics { 
    public class Class1 { 
     public static void Run() { 
      // Stuff... 
     } 
    } 
} 

Aggiungi una nuova libreria di classi C++/CLI al tuo progetto. Fare clic con il tasto destro del mouse sulla soluzione, Aggiungi, Nuovo progetto. Aprire il nodo "Altre lingue", Visual C++, CLR e selezionare il modello di progetto "Libreria di classi". Fare clic con il tasto destro del mouse sul nuovo progetto, Proprietà, Proprietà comuni, Framework e Riferimenti, quindi fare clic sul pulsante Aggiungi nuovo riferimento. Dalla scheda Progetti, seleziona il progetto C# di cui vuoi esportare i metodi.

Eliminare la classe vuota pre-compilata con la TODO commento // e scrivere questo tipo di codice:

extern "C" __declspec(dllexport) 
void __stdcall Example() 
{ 
    Publics::Class1::Run(); 
} 

generare la soluzione. Verificare che la funzione Example sia stata esportata eseguendo dumpbin.exe/exports nella DLL.Si dovrebbe vedere qualcosa di simile a questo:

 1 0 00001020 [email protected] = [email protected] 

Al di là del nome e la convenzione di chiamata, ora avete anche un sacco di opzioni per ottimizzare la funzione esportata. Se si desidera esportare un metodo di istanza, invece di un metodo statico si potrebbe scrivere la funzione in questo modo, per esempio:

extern "C" __declspec(dllexport) 
void __stdcall Example() 
{ 
    Publics::Class1^ obj = gcnew Publics::Class1; 
    obj->Run(); 
} 

Etcetera, una certa familiarità con il linguaggio C++/CLI è necessario se si sta andando a rendere questo elaborato . Ultimo ma non meno importante, è anche probabile che tu scopra cosa è andato storto nel tuo tentativo originale di far funzionare il rewriter di Giesecke. In caso contrario utilizza la stessa identica tecnica utilizzata dal compilatore C++/CLI per esportare il metodo gestito.

+2

+1 apprezzo molto questo tutorial. Ho imparato qualcosa. Ho sempre dato per scontato che UnmanagedExports eseguisse una sorta di magia nera. Molto bello da imparare altrimenti. –

+0

funziona in mono? – denfromufa

+0

La funzione "Example()" dall'assembly/DLL in modalità mista creata compilando la libreria di classi C++/CLI inserita nel post sarà accessibile dal codice UNmanaged (es. Delphi, nativo C++) come se fosse un normale puro non gestito DLL? Il CLR viene avviato automaticamente quando il codice non gestito richiama la funzione esportata? –