Gå til innhold

Anbefalte innlegg

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
Videoannonse
Annonse

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

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 av Hayer
Lenke til kommentar

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

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

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 konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...