P/Invoke - Problem System.EntryPointNotFoundException
-
Ich versuche ein .NET Binding für Qt zu erstellen. Um dies zu bewerkstelligen muss ich ein C-Interface bauen. Beim Ausführen eines Testprogramms wird allerdings {"Unable to find an entry point named 'qi_widget_new' in DLL 'qi_gui_c.dll'.":""} durch System.EntryPointNotFoundException gemeldet.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; namespace Qi.Gui { public class Widget : IDisposable { public Widget() { thisWidget = qi_widget_new(); } private IntPtr thisWidget; public void Dispose() { qi_widget_delete(thisWidget); } public void Show() { qi_widget_show(thisWidget); } public void Resize(int width, int height) { qi_widget_resize(thisWidget, width, height); } [DllImport("qi_gui_c.dll")] private extern static IntPtr qi_widget_new(); [DllImport("qi_gui_c.dll")] private extern static void qi_widget_delete(IntPtr thisArg); [DllImport("qi_gui_c.dll")] private extern static void qi_widget_show(IntPtr thisArg); [DllImport("qi_gui_c.dll")] private extern static void qi_widget_resize(IntPtr thisArg, int width, int height); } }
#ifndef QI_WIDGET #define QI_WIDGET //struct qi_widget; extern "C" void* qi_widget_new(void); extern "C" void qi_widget_delete(void*); extern "C" void qi_widget_show(void*); extern "C" void qi_widget_resize(void*, int, int); #endif
static void Main(string[] args) { var widget = new Widget(); widget.Resize(800, 500); widget.Show(); }
Was könnte der Fehler sein? Schönen Maianfang
-
Schau mal mit dem Dependency Walker nach, ob und wie die Funktionen in der erzeugten DLL heißen. Hast du denn auch bei der Implementierung der Funktionen
extern "C"
verwendet?
P.S. Das Dispose() solltest du richtig implementieren, s. Beispiel in Implementieren einer Dispose-Methode (beachte die "protected virtual Dispose(bool disposed)"-Methode!)
-
Mit was kompilierst du den C Code? Womöglich MSVC? Hast du
__declspec(dllexport)
vergessen?Grüssli
-
Nein das war eigentlich absicht, aber da das Module im Dependency Walker keine Funktionen angezeigt bekommt, muss ich wohl darüber nachdenken.
http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx schrieb:
dllexport of a C++ function will expose the function with C++ name mangling. If C++ name mangling is not desired, either use a .def file (EXPORTS keyword) or declare the function as extern "C".
-
Zeus schrieb:
Nein das war eigentlich absicht, aber da das Module im Dependency Walker keine Funktionen angezeigt bekommt, muss ich wohl darüber nachdenken.
http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx schrieb:
dllexport of a C++ function will expose the function with C++ name mangling. If C++ name mangling is not desired, either use a .def file (EXPORTS keyword) or declare the function as extern "C".
Ehm, ja und was willst du mit dem Zitat sagen?
__declspec(dllexport)
sagt nichts über das Name-Mangling aus. Es sagt dem Kompiler, dass die Funktion exportiert werden soll. Egal welches Name-Mangling verwendet wird. Du kannst mit__declspec(dllexport)
auch C++ Klassen oder Funktionen exportieren. Sobald du etwas aus einer DLL exportierst, brauchst du in MSVC ein__declspec(dllexport)
davor.
extern "C"
ist nur dazu da, dass du die Funktion einfach identifizieren kannst.extern "C"
sagt nichts darüber aus, ob eine Funktion exportiert wird oder nicht.Grüssli
-
Ja, Danke