Hayer Skrevet 9. juni 2010 Del Skrevet 9. juni 2010 Hei Har en DLL(har ikke kildekoden) med et par funksjoner som jeg har nødt til å kalle fra C#.Net(Express 2008). Hvis jeg laster DLL i Dependency Walker ser funksjonene slik ut: ?xenoAddRigidBodyPointImpulse@@YAXHMMMMMM@Z ?xenoAddRigidBodyTorque@@YAXHMMM@Z ?xenoCharacterControllerCrouch@@YAXH@Z ?xenoCharacterControllerJump@@YAXH@Z ?xenoCharacterDisable@@YAXH@Z ?xenoCharacterEnable@@YAXH@Z ?xenoDeleteRigidBody@@YAXH@Z ?xenoEnd@@YAXXZ Har prøvd med DllImport on EntreyPoint="?xenoEnd@@YAXXZ", men det returnerer bare en feil. Noen som har noe peiling? Tenkte jeg kanskje måtte wrappe den orgianle DLLen inn i en ny C++ DLL som C#.Net kan kalle direkte. Er dette veien å gå? Lenke til kommentar
GeirGrusom Skrevet 9. juni 2010 Del Skrevet 9. juni 2010 Du må nok nesten lage en wrapper klasse i C++/CLI. Visual C# støtter ikke C++ ABI. Lenke til kommentar
Hayer Skrevet 9. juni 2010 Forfatter Del Skrevet 9. juni 2010 Ok, her er C++ DLLen jeg har skrevet nå #include <windows.h> // The following ifdef block is the standard way of creating macros which make exporting // from a DLL simpler. All files within this DLL are compiled with the XENOWRAPPERWIN32_EXPORTS // symbol defined on the command line. this symbol should not be defined on any project // that uses this DLL. This way any other project whose source files include this file see // XENOWRAPPERWIN32_API functions as being imported from a DLL, whereas this DLL sees symbols // defined with this macro as being exported. #ifdef XENOWRAPPERWIN32_EXPORTS #define XENOWRAPPERWIN32_API __declspec(dllexport) #else #define XENOWRAPPERWIN32_API __declspec(dllimport) #endif typedef void (*FunctionFunc)(); typedef void (*FunctionFuncFloat)(float); typedef void (*FunctionFuncInt)(int); typedef void (*FunctionIntFloatFloatFloat)(int,float,float,float); // This class is exported from the xeno wrapper win32.dll class XENOWRAPPERWIN32_API Cxenowrapperwin32 { public: Cxenowrapperwin32(void); HINSTANCE libInstance; // FunctionFunc curFunc; // Library base functions void LoadLib() { libInstance = LoadLibrary(L"F:\\xenophysics.dll"); } void UnloadLib() { FreeLibrary(libInstance); } // Function calls to the xeno physics void xStart() { FunctionFunc curFunc; curFunc = (FunctionFunc)GetProcAddress(libInstance, "?xenoStart@@YAXXZ"); curFunc(); } void xEnd() { FunctionFunc curFunc; curFunc = (FunctionFunc)GetProcAddress(libInstance, "?xenoEnd@@YAXXZ"); curFunc(); } void xUpdate() { FunctionFunc curFunc; curFunc = (FunctionFunc)GetProcAddress(libInstance, "?xenoUpdate@@YAXXZ"); curFunc(); } void xMakeRigidBodyStaticBox(int objid) { FunctionFuncInt curFunc; curFunc = (FunctionFuncInt)GetProcAddress(libInstance, "?xenoMakeRigidBodyStaticBox@@YAXH@Z"); curFunc(objid); } void xMakeRigidBodyDynamicBox(int objid) { FunctionFuncInt curFunc; curFunc = (FunctionFuncInt)GetProcAddress(libInstance, "?xenoMakeRigidBodyDynamicBox@@YAXH@Z"); curFunc(objid); } void xSetRigidBodyPosition(int objid, float x, float y, float z) { FunctionIntFloatFloatFloat curFunc; curFunc = (FunctionIntFloatFloatFloat)GetProcAddress(libInstance, "?xenoSetRigidBodyPosition@@YAXHMMM@Z"); curFunc(objid, x, y, z); } void xSetGravity(float grav) { FunctionFuncFloat curFunc; curFunc = (FunctionFuncFloat)GetProcAddress(libInstance, "?xenoSetGravity@@YAXM@Z"); curFunc(grav); } }; extern XENOWRAPPERWIN32_API int nxenowrapperwin32; XENOWRAPPERWIN32_API int fnxenowrapperwin32(void); og slik bruker jeg den i C#.Net [DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?LoadLib@Cxenowrapperwin32@@QAEXXZ")] public static extern void LoadLib(); [DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?UnloadLib@Cxenowrapperwin32@@QAEXXZ")] public static extern void UnloadLib(); [DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?xStart@Cxenowrapperwin32@@QAEXXZ")] public static extern void xStart(); [DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?xUpdate@Cxenowrapperwin32@@QAEXXZ")] public static extern void xUpdate(); [DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?xEnd@Cxenowrapperwin32@@QAEXXZ")] public static extern void xEnd(); [DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?xMakeRigidBodyDynamicBox@Cxenowrapperwin32@@QAEXH@Z")] public static extern void xMakeRigidBodyDynamicBox(int objid); [DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?xMakeRigidBodyStaticBox@Cxenowrapperwin32@@QAEXH@Z")] public static extern void xMakeRigidBodyStaticBox(int objid); [DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?xSetGravity@Cxenowrapperwin32@@QAEXM@Z")] public static extern void xSetGravity(float grav); [DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?xSetRigidBodyPosition@Cxenowrapperwin32@@QAEXHMMM@Z")] public static extern void xSetRigidBodyPosition(int obj, float x, float y, float z); Problemet er at når jeg bruker LoadLib() for å laste det inn så får jeg bare feilen Attempted to read or write protected memory. This is often an indication that other memory is corrupt. What2do? :3 Lenke til kommentar
GeirGrusom Skrevet 9. juni 2010 Del Skrevet 9. juni 2010 http://www.codeproject.com/KB/mcpp/quickcppcli.aspx#A8 Lenke til kommentar
Hayer Skrevet 9. juni 2010 Forfatter Del Skrevet 9. juni 2010 (endret) Sikkert et utroilig dumt spørsmål, men hvordan "inkludere" jeg DLL jeg skal wrappe i C++ CLR DLLen min? Hva gjør jeg hvis DLLen jeg skal wrappe ikke har en klasse? :s Edit: Kan kanskje være vitalt å si at jeg KUN har .DLL filen jeg skal wrappe, ikke noe mer. Endret 9. juni 2010 av Hayer Lenke til kommentar
GeirGrusom Skrevet 9. juni 2010 Del Skrevet 9. juni 2010 Du har vel en header fil for den også? Ellers ville jeg sagt det er ganske vanskelig å gjøre dette... Du må ha en .lib fil og en .h fil, ellers blir det temmelig vanskelig å få til. Lenke til kommentar
HDSoftware Skrevet 14. juni 2010 Del Skrevet 14. juni 2010 Du trenger strengt tatt ikke noe .h fil tror jeg. Jeg importerer massevis av DLL'er inn i .NET uten å ha noe h fil. Holder lenge med selve DLL'en. Men du MÅ selvsagt kjenne prototypen. Du tar med deg alle disse raritetene etter entrypointet ser jeg. Det gjør aldri jeg. Kan det være det som er problemet. Dette er et eksempel på hvordan jeg gjør det i kombinasjonen Clarion og .NET DllImport("SharedDLL04", EntryPoint="TAKESANDRETURNSGROUP")] public static extern void TakesAndReturnsGroup(ref TestGroup pTestGroup); Lenke til kommentar
GeirGrusom Skrevet 14. juni 2010 Del Skrevet 14. juni 2010 For C++ DLL-er må du ha en .lib fil og en .h fil. .h filen er prototypen, og uten den kommer du ikke langt. Det er mulig det går an å lage en .lib fil utifra en .dll fil, men du må i hvertfall ha en header som forklarer klassene, datatypene osv. som brukes i fila. Igjen: .NET støtter ikke C++ ABI, kun C. Det er derfor ikke mulig å bruke C++ Dll-er direkte i C# eller Visual Basic (bortsett fra COM-dll-er) Det finnes sikkert måter å gjøre det på, som for eksempel med direkte CIL(Common Intermediate Language) via System.Reflection.Emit, men ellers skal en helst bruke C++/CLI til dette, da dette språket støtter C++ direkte. Lenken jeg ga tidligere viste link til en artikkel som omhandler hvordan man skal wrappe native code C++ programmer i C++/CLI. Dette skal til slutt gjøre at du får en .dll som du kan bruke direkte i C#. For C programmer er det ganske enkelt som HDSoftware sier. Dersom den skrives i C++ må all kode som skal eksporteres (med __declspec(dllexport)) skrives inne i extern "C" blokker. extern "C" { __declspec(dllexport) int __stdcall SomeFunction() { return 42; } } Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå