Hi,
Also es geht darum :
#include <windows.h>
#define ST_BYREF 0x00000001L
#define ST_MATRIX 0x00000010L
#define ST_CLASS 0x00000100L
#define DLL_API __declspec(dllimport)
typedef void tvar;
typedef void app;
typedef void tbytecode;
typedef void (*_InitPPL) ();
[...]
typedef tvar *(*_SetVariable)(app *a, char *name, char *s, double d, char *ptr, int size);
[...]
HINSTANCE ppllib;
_InitPPL InitPPL;
[...]
_VSetVariable VSetVariable;
[...]
bool InitializePPL ()
{
HINSTANCE h = LoadLibrary(TEXT("ppl.dll"));
ppllib = h;
if (h != NULL)
{
InitPPL = (_InitPPL)GetProcAddress(h, TEXT("InitPPL"));
[...]
VSetVariable = (_VSetVariable)GetProcAddress(h, TEXT("VSetVariable"));
[...]
InitPPL();
return true;
}
return false;
}
halt n normaler c++ header für funktionen einer dll die ich gerne benutzen würde.
mein versuch das in c# zu schreiben sieht so aus :
protected delegate void tvar();
protected delegate void app();
protected delegate void tbytecode();
[DllImport("ppl.dll")]
protected static extern uint InitPPL();
[...]
[DllImport("ppl.dll")]
protected static unsafe extern tvar SetVariable(app *a, char *name, char *s, double d, char *ptr, int size);
[...]
public void Initialise()
{
InitPPL();
}
das endet beim compilen damit : "cannot take the address or size of a variable of a managed type (...app)"
ich hab erst vor kurzem mit c# begonnen und weiss eigentlich gar nicht wie ich das richtig angehn soll. ich bin mir sicher das lässt sich ganz anders viel besser - und vor allem mit funktion lösen^^
also i wär jedem sehr verbunden der mir da weiterhelfen kann.
mfg
Versuchs mal so:
[DllImport("ppl.dll")]
protected static extern tvar SetVariable(app a, char name, char s, double d, char ptr, int size);
Normalerweise musst du in C# nicht angeben, dass es sich um ein Pointer hadelt. Da eine Referenz übergeben wird und die C++ Funkion auf die Speicherstellen zugreift.
Also zumindest hat das bei mir bisher immer funktioniert.
Falls es sich bei Char s um eine Zeichenkette handeln kannst du ein C# String verwenden.
Ich hoffe ich konnte dir ein bissi weiterhelfen.
Gruß
LordK
Programmieren in C# hält die grauen Zellen am Leben.
Es schärft alle fünf Sinne: den Schwachsinn, den Blödsinn, den Wahnsinn, den Unsinn und den Stumpfsinn.
danke dir, es lässt sich zumindest jetzt compilen =) ob es denn letztendlich funktioniert finde ich auch noch raus^^
noch eine kleinigkeit :
typedef void (*_NewFunction) (char *name, void *pointer, int in, int out);
protected static extern uint NewFunction(char name, void pointer, int _in, int _out);
das void pointer, es soll an der stelle wohl der pointer auf eine c++ funktion übergeben werden , void is in c# allerdings nicht erlaubt , gibt es da eine alternative?
Original von SmokingFish
danke dir, es lässt sich zumindest jetzt compilen =) ob es denn letztendlich funktioniert finde ich auch noch raus^^noch eine kleinigkeit :
typedef void (*_NewFunction) (char *name, void *pointer, int in, int out);
protected static extern uint NewFunction(char name, void pointer, int _in, int _out);
das void pointer, es soll an der stelle wohl der pointer auf eine c++ funktion übergeben werden , void is in c# allerdings nicht erlaubt , gibt es da eine alternative?
Hm is mir jetzt nichts bekannt. Vielleicht könntest du mal probieren das Void einfach weg zu lassen. Falls da auch nichts übergeben werden soll, könntest du "null" verwenden. Damit würdest du aber nur die Parameterliste füllen und nichts übergeben.
Aber das man irgendetwas in c++ void übergeben kann wusste ich auch nicht.
Gruß
LordK
Programmieren in C# hält die grauen Zellen am Leben.
Es schärft alle fünf Sinne: den Schwachsinn, den Blödsinn, den Wahnsinn, den Unsinn und den Stumpfsinn.
leider doch..allerdings hab i noch ganz andere probleme ^^
i fang ma an :
[DllImport("ppl.dll")]
protected static extern tvar GetVariable(app a, string name,ref string s,ref double d, string ptr);
public string GetVariable(string Variable)
{
string s = "";
double d = 0;
tvar v = GetVariable(null,Variable,ref s,ref d, null);
return s;
}
erstma das , eigentlich sollte das doch jetzt stimmen (der aufruf), allerdings bekomm i für die zeile "tvar v = .." den fehler "function pointer was not created by a delegate" (also compiliert , beim testen der funktion)
problem 2 :
void testfunc ()
{
}
NewFunction("testfunc", &testfunc, 1, 0);
also i muss irgentwie die testfunc als parameter übergeben, nur wie is mir ein rätsel wenn es "void" als typ in c# nicht gibt.
Du solltest die Variablen nicht mit ref übergeben. Der C-Code geht automatisch auf die Speicherstelle der Variablen.
Programmieren in C# hält die grauen Zellen am Leben.
Es schärft alle fünf Sinne: den Schwachsinn, den Blödsinn, den Wahnsinn, den Unsinn und den Stumpfsinn.
Für void* schreibt man IntPtr wenn es safe Code sein soll.
Wenn du deinen Code als unsafe markierst, kannst du auch ganz normal Pointer nehmen.
Wichtig ist nur, dass die Funktionen wenn sie mit nem C++ Compiler kompiliert wurden, als extern "C" deklariert werden. (Stichwort: Name Mangling)
tvar, app und Andere kannst du natürlich nicht nutzen. Du musst schon die Datentypen des CTS nehmen 😉
Außerdem solltest du auch auf den richtigen Namen für die Funktion achten. In deinem Code unten heißt die Funktion die du lädst "VSetVariable". In deinem C#-Code schreibst du aber nur "SetVariable". (EntryPoint benutzen)
DllImport noch mal kurz erklärt:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/vcwlkSysimportAttributeTutorial.asp
I am Jack's smirking revenge.
I am Jack's raging bile duct.
I am Jack's cold sweat.
I am Jack's complete lack of surprise.
I am Jack's broken heart.
I am Jack's wasted life.
das ich void* nutzen kann wenn ich unsafe benutze hab i auch rausgefunden. app usw scheine ich wirklich nicht nutzen zu können ohne die typen wirklich zu kennen (im orginal c++ code hat das funktioniert). aber die sind für die funktionen die ich brauche nicht notwendig. und das Get/Set Variable, das sind 2 funktion je, VSet/VGet gibt es auch noch. ne letzte frage noch (hoffe es is die letzte^^) : wenn ich nun void* als parameter habe, wie kann ich ich eine normale funktion als parameter übergeben? (void*) zum umwandeln funzt net, da wird bestimmt ne funktion geben^^
Wenn du einen Funktionszeiger als Paramter für eine andere Funktion übergeben willst (Callback-Funktion), dann musst du einen Delegaten nutzen.
Wie sowas aussieht kannst du hier sehen:
http://www.dotnet247.com/247reference/msgs/55/276613.aspx
Im 2.0 Framework gibt es sogar die Möglichkeit einen nativen Function-Pointer direkt in einen Delegaten umzuwandeln.
I am Jack's smirking revenge.
I am Jack's raging bile duct.
I am Jack's cold sweat.
I am Jack's complete lack of surprise.
I am Jack's broken heart.
I am Jack's wasted life.