Frage

Ich habe eine C ++ DLL gebaut, die Ich mag würde von C # -Code nennen. Ich bin in der Lage eine Funktion aufzurufen, aber die andere wirft eine Ausnahme, wenn der C # -Code versucht, die DLL zu laden.

Der Header sieht wie folgt aus:

extern "C" __declspec(dllexport) BOOL Install();
extern "C" __declspec(dllexport) BOOL PPPConnect();

Dies erzeugt eine dll mit etwas verwirrend Exporte Tabelle (was bedeutet foo = foo im Namensfeld bedeuten?):

File Type: DLL

Section contains the following exports for PPPManager.dll

00000000 characteristics
499F44F0 time date stamp Fri Feb 20 16:04:00 2009
    0.00 version
       1 ordinal base
       2 number of functions
       2 number of names

ordinal hint RVA      name

      1    0 000078E4 Install = Install
      2    1 000079DC PPPConnect = PPPConnect

Meine P / Invoke Erklärungen wie folgt aussehen:

[DllImport("PPPManager.dll")]
private static extern bool Install();

[DllImport("PPPManager.dll")]
private static extern bool PPPConnect();

Der Aufruf von Install kehrt ohne Ausnahme, aber wenn ich PPPConnect nennen, erhalte ich ein Missing - „Kann nicht einen Einstiegspunkt‚PPPConnect‘in PInvoke DLL‚PPPManager.dll‘gefunden“

Ich habe versucht, die extern und declspec Direktiven aus der Funktionsdeklaration Installation zu entfernen, so dass PPPConnect die einzige Funktion ausgeführt ist, und dies immer noch nicht lassen Sie mich PPPConnect nennen.

Ich habe auch versucht, durch die Ordnungs des DllImport tun; dies gibt das gleiche Ergebnis wie beim Namen nennen -. Installieren Sie kehren, aber PPPConnect wirft die Ausnahme „Kann nicht einen Einstiegspunkt‚# 2‘finden ...“

Das Interop-Protokoll gibt:

[pinvokeimpl][preservesig]
bool  invivodata.Common.System.IPAQUtils::Install();
BOOLEAN (I1_WINBOOL_VAL) Install();

JIT ERROR FOR PINVOKE METHOD (Managed -> Native): 
[pinvokeimpl][preservesig]
bool  invivodata.Common.System.IPAQUtils::PPPConnect();
BOOLEAN (I1_WINBOOL_VAL) PPPConnect();
Diese

ist auch außerhalb mein Fachgebiet, so irgendwelche Vorschläge oder Gedanken wäre willkommen.

Danke, Paul

edit: Es stellt sich heraus, dass dieser Code funktioniert; das Problem war mit der neuesten dll auf das Gerät nicht weitergegeben werden. D'oh!

War es hilfreich?

Lösung

Verwenden Sie eine DEF-Datei in Ihrem DLL-Projekt diese Funktionen zu exportieren? Wenn ja, entfernen Sie es und versuchen Sie es erneut. Dies ist nur eine Vermutung, weil es sieht aus wie Ihre Exporte sind nicht das, was sie sein sollten, wenn Sie eine extern „C“ declspec (dllexports) tun.

Ich habe versucht, dies aus mit einem einfachen C ++ dll mit

extern "C" __declspec(dllexport) BOOL Install();
extern "C" __declspec(dllexport) BOOL PPPConnect();

und ein einfach C # app mit Ihren PInvoke Erklärungen und es funktionierte gut.

Wenn ich habe eine dumpbin / export auf dem dll ich sah:

Dump der Datei PPPManager.dll

Dateityp: DLL

Abschnitt enthält die folgenden Exporte für PPPManager.dll

00000000 characteristics
499F6C2D time date stamp Fri Feb 20 20:51:25 2009
    0.00 version
       1 ordinal base
       2 number of functions
       2 number of names

ordinal hint RVA      name

      1    0 000110CD Install = @ILT+200(_Install)
      2    1 00011069 PPPConnect = @ILT+100(_PPPConnect)

Beachten Sie, dass die exportierten Namen unterschiedlich sind in meinem Fall.

Andere Tipps

Es könnte etwas so einfach wie PPPConnect in eine Art und Weise versagt, die von den OS falsch interpretiert wird. Versuchen Umsetzung sowohl Install und PPPConnect als No-ops (nur haben sie TRUE zurück, ohne etwas anderes zu tun) und sehen, ob der Fehler weiterhin besteht. Wenn ja, versucht die Reihenfolge tauschen, in der sie ausgeführt werden (immer noch als No-ops) und sehen, ob das Problem mit der Bestellung (unwahrscheinlich) oder an etwas anderes gebunden ist.

Sie können auch das grafische Tool depends verwenden, was die Exporte Tabelle DLL bestätigen aussieht, aber ich bezweifle, das Problem aus diesen Vierteln kommt.

Nach Ihrer Beschreibung Installieren und PPPConnect unterscheidet sich nur in Namen. Ich denke, man einfach alte DLL-Version mit C # Anwendung verwenden. A eine ohne PPPConnect definiert.

Die Erklärungen sehen rechts (soweit ich ohne Quellen beurteilen kann).

Große Informationen, aber wie Sie erwähnen, ist hier alles in Ordnung. Versuchen Sie, Debugging Tools für Windows und ausgeführt wird:

kd -z \path\to\PPPManager.dll -y \path\to\PPPManager.pdb -c "x pppmodule!*"

ein besseres Abbild der Symboltabelle zu erhalten; es ist ein blinder Schuss als auch, aber man könnte auch versuchen:

extern "C" 
{
    __declspec(dllexport) BOOL Install();
    __declspec(dllexport) BOOL PPPConnect();
};

Bei der __declspec tut etwas seltsam.

Dependency Walker verwenden und öffnen Sie Ihre DLL, um zu überprüfen, welche Methoden verfügbar sind

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top