Aufruf Visual Basic-DLL in C++
Ich erworben habe eine DLL, die erstellt wurde in Visual Basic von einem Drittanbieter(Sensor DLL.dll). Diese DLL enthält Funktionen für das Gespräch ein sensor, und ich brauche, um diese Funktionen aufrufen aus einem Visual C++ Programm, das ich Schreibe. Der Verkäufer wird sich nicht stellen Sie eine header-Datei, und ich weiß nicht Visual Basic. Wenn ich die header-Datei wäre dies ein 15 Minuten Projekt... stattdessen bin ich immer noch mit ihm zu kämpfen, eine Woche später. Bitte Um Hilfe!!
Mir wird gesagt, dass eine Funktion (Get_Data) in der DLL ist von der form:
Public Function Get_Data(ByVal Handle As String) As String
Ich habe versucht, verschiedene Methoden für den Aufruf dieser Get_Data-Funktion ohne Erfolg:
Methode 1) das DllImport-Attribut
#using <mscorlib.dll>
using namespace System::Runtime::InteropServices;
namespace Sensor
{
[DllImport("Sensor DLL.dll", EntryPoint = "Get_Data", CharSet = System::Runtime::InteropServices::CharSet::Unicode)]
BSTR Get_Data(BSTR Handle);
}
//then I call the function
Sensor::Get_Data(Handle);
Diese Methode scheint der nächste, den ich gelernt habe, einen sloution. Es kompiliert, aber gibt den folgenden Fehler, wenn es ausgeführt wird:
Eine nicht behandelte Ausnahme des Typs 'System.EntryPointNotFoundException " ist aufgetreten
Weitere Informationen: kann Nicht finden, einen Einstiegspunkt namens 'Get_Data' in der DLL "Sensor DLL.dll'.
Habe ich versucht verschiedene Datentyp-Kombinationen/Permutationen neben BSTR einschließlich BSTR*, wchar_t, int, etc. Es ist möglich, dass ich eine verpasst, aber jeden Datentyp gibt den gleichen Fehler.
Methode 2) dllimport-storage-class-Attribut
__declspec(dllimport) BSTR Get_Data(BSTR Handle);
//then I call the function
Get_Data(Handle);
Diese Methode ist verwirrend für mich, weil ich don ' T geben Sie die DLL, die ich importieren möchten aus. Ich habe kopiert die DLL in den Projekt-Ordner und ich habe ihn Hinzugefügt, um das Projekt manuell, also hoffentlich bedeutet dies, dass es gefunden werden kann. Beim kompilieren wird der linker liefert den folgenden Fehler:
error LNK2028: nicht aufgelöstes token (0A00034F) "wchar_t * __cdecl Get_Data(wchar_t *)" (?Get_Data@@$$FYAPA_WPA_W@Z), verwiesen in Funktion "" int __cdecl main(void)" (?main@@$$HYAHXZ)
error LNK2019: nicht aufgelöstes externes symbol "wchar_t * __cdecl Get_Data(wchar_t *)" (?Get_Data@@$$FYAPA_WPA_W@Z), verwiesen in Funktion "" int __cdecl main(void)" (?main@@$$HYAHXZ)
Ich vermutete, dass dies vielleicht gemeint, ich sollte mit wchar_t oder wchar_t* anstelle des BSTR, aber ändern, um entweder datatype Ergebnisse in die gleichen Fehler.
Methode 3) GetProcAddress
typedef BSTR (*Get_Data_Ptr)(BSTR Handle);
HINSTANCE LoadMe;
LoadMe = LoadLibraryA("Sensor DLL.dll");
if (!LoadMe)
std::cout << "\nDLL failed to load!\n";
Get_Data_Ptr LibMainGet_Data;
LibMainGet_Data = (Get_Data_Ptr)GetProcAddress(LoadMe,"Get_Data");
//then I call the function
LibMainGet_Data(Handle);
Dies kompiliert, gibt aber die folgende Fehlermeldung beim ausführen:
Eine nicht behandelte Ausnahme des Typs 'System.AccessViolationException " ist
Weitere Informationen: Versucht, Lesen oder schreiben von geschütztem Speicher. Dies ist Häufig ein Hinweis darauf, dass anderer Speicher beschädigt ist.
Wenn ich die Maus über die verschiedenen Teile der code im debug-Modus scheint es, dass, wie die erste Methode, es war auch nicht in der Lage zu finden, die 'Get_Data' Einstiegspunkt in der DLL.
Hat jemand aufgerufenen Funktionen aus einer VB-DLL mit C++, wenn du nicht die DLL selbst und die Sie nicht haben .idl-Dateien, etc? Hat jemand ein funktionierendes Beispiel, wie dieses könnten Sie teilen?
Danke!
- Attribute sind nicht verfügbar in C++. Nur in managed C++, das ist nicht das gleiche
- Sind Sie absichtlich mit C++/CLI? Oder sind Sie es einfach benutzen, weil es der einzige Weg ist der Aufruf von COM-Objekten, die Sie mit vertraut sind?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einer VB6 DLL ist normalerweise ein COM-server. Sie haben in der Tat äquivalent zu einer .h-Datei, es ist eine Art Bibliothek, in Sie eingebettet sind. Start mit Projekt + Eigenschaften Allgemeine Eigenschaften-Framework und Verweise. Neuen Verweis hinzufügen-Schaltfläche, Registerkarte "Durchsuchen", wählen Sie die DLL.
Nächsten, Sicht + - Objekt-Browser. Sie sollten die generierten Interop-Bibliothek in der Liste. Öffnen Sie die Knoten, um zu sehen, was da ist. Sie schreiben normal von verwaltetem code, wie gcnew, zum erstellen des COM-Objekts und Aufruf der Methoden der Schnittstelle. Sie brauchen eine gewisse Mindest-Dokumentation der verfügbaren Methoden, um eine Vermutung an, wie Sie genannt werden sollte.
Ich glaube, das fehlende Stück ist die Aufrufkonvention. C++ hat seine eigene Funktion die Aufrufkonvention anders als VB6 (ich nehme an, VB6, da Sie noch nicht angegeben VB.NET ausdrücklich). VB6 verwendet STDCALL-Konvention in der Erwägung, dass C++, je nach Anbieter, verwendet eine andere Aufrufkonvention als __cdecl, das ist, warum Sie sehen, die __cdecl-in der compiler-Fehler, Zeile für Methode #2. Es wird davon ausgegangen, dass externe Funktion verwendet, die Aufruf-Konvention standardmäßig. Die Aufrufkonvention ist ein Satz von Regeln, die beschreiben, wie die Funktionen sich gegenseitig aufrufen; insbesondere darüber, wie die Register verwendet werden, in welcher Reihenfolge die Parameter geliefert werden, wie by value /by-Referenz bestimmt wird, etc.
Ich würde vorschlagen, kleben mit Methode #3, da die Methode #1 ist für Managed C++ ist nicht C++ - standard, und mit der Methode #2, die mir nicht vertraut und sieht ein bisschen zweideutig. Was Sie versuchen wollen, ist das deklarieren der Funktionszeiger typedef, um STDCALL verwenden.
In der OLE - /COM-viewer, um die COM-Typbibliothek in eine dll/exe/..., die Sie haben, um es zu öffnen, indem Sie unter "Datei->Ansicht Typbibliothek" anstelle von "Datei->Bind to File"
Es klingt wie die DLL ist nicht der Export einer Funktion namens
Get_Data
. Öffnen Sie eine Eingabeaufforderung, und verwenden Sie dumpbin, um die Liste der Exporte der DLL, z.B.:(dumpbin.exe befindet sich im VC\bin, in Ihre Visual Studio-Installation Ordner, die istypically etwas wie
C:\Program Files\Microsoft Visual Studio 10.0
).Dann ersetzen Sie
Get_Data
mit dem tatsächlichen Einstiegspunkt und sehen, wenn Sie irgendwelche mehr Glück.Einem Visual basic-Programm normalerweise benötigt eine Laufzeitumgebung, um Sie auszuführen.
Wenn Sie ein COM-Objekt (implementiert in VB) mit der COM-API zur Kommunikation mit C++. Haben Sie zum registrieren der COM-ersten. Hier ist ein thread, der erklärt, heißen, das zu tun: http://forums.devx.com/archive/index.php/t-87059.html
Wenn Sie verwenden ein .NET-Sprache, die Methode von Hans Passant mit einer Referenz, erstellen Sie eine interop-dll für dich. Das ist viel viel einfacher.
Sogar Methode 3 mit den richtigen Namen ist wahrscheinlich fehl, weil wenn es ein COM-Objekt benötigen Sie jedoch eine Umgebung namens Appartment verwenden Sie die COM-Objekte. Sie "geben Sie" diese Wohnung durch den Aufruf
CoInitialize
. Das schafft einige Magische Sachen in die TLS (Thread Local Storage), um die COM-Magie. Ich hoffe, dass dies erklärt, warum versucht wird sinnlos, wenn die DLL, die haben passiert eine COM-Komponente, was ziemlich wahrscheinlich nach der ATL-wie benennen wir sehen können.BEARBEITEN:
Ich vergaß zu sagen, dass Sie können auch leicht sehen, was in der dll, wenn es sich um eine COM mit der OLE/COM Viewer (in der Regel, wenn Sie einen compiler, den Sie werden, wie ein Werkzeug um).