| 

.NET C# Java Javascript Exception

2
Hallo zusammen,
ich habe hier ein echtes Problem.
Ich möchte aus einer C/C++ - Funktion einen char* an c# zurüclgeben (Fkt. siehe unten).

Ich habe keine Ahnung wie ich den char* in c# entgegennehme:

C#:
private unsafe void button1_Click(object sender, EventArgs e)
{
//Welchen Datentyp benötoge ich um char* entgegenzunehmen
byte[] b= u.PrepareToSend(44); //Objekt u ist angelegt
}
}


C/C++:
unsigned  char* PrepareToSend(float SET)
{
unsigned char* send= (unsigned char *) malloc(40 * sizeof(unsigned char));
//...
return send;
}



Danke und viele Grüße,

Maik
News:
01.06.2011
Maik_1978 674 1 8
1
Hallo Maik,
wenn die Angaben in Deinem Profil stimmen, so hast Du bislang 18 Fragen gestellt, bei keiner davon eine Antwort als richtig akzeptiert und genau 1 (eine) Bewertung vergeben. Wenn Du so oft fragst, vermute ich, dass die Antworten Dir auch etwas bringen. Dann sei bitte auch so nett und bedanke Dich für die Hilfe mit Bewertungen. So ist es hier üblich. Dankeschön!
Matthias Hlawatsch 10.06.2011
2 Antworten
2
Hallo Maik,

das sollte mit P/Invoke gehen. Du deklarierst in C# Deine C-Funktion etwa so (ungetesteter Code):
[DllImport("DeineDLL.dll")]
[return: MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.U1, SizeConst=40)]
private static extern byte[] PrepareToSend(float SET);

und rufst sie dann "ganz normal" auf:
private void button1_Click(object sender, EventArgs e)
{
byte[] b = PrepareToSend(44);
}

Was der passende Rückgabetyp ist, ist eine nicht ganz so einfach zu beantwortende Frage, die auch vom Kontext abhängt. Ich habe aus Deinem Beispiel geschlossen, dass Du das Array in C# als byte[] sehen willst, und dass es eine feste Länge hat. In dem Fall sollte die MarshalAs-Deklaration in meinem Beispiel funktionieren (wie gesagt: ungetestet, und der ArraySubType kann u.U. weggelassen werden). Falls es sich tatsächlich eher um einen String handeln sollte, mußt Du anders vorgehen. Offen ist auch noch die Frage, wann und von wem der allokierte Speicher wieder freigegeben werden soll.

Vielleicht hilft Dir auch noch das Tool PInvoker weiter.
01.06.2011
Matthias Hlawatsch 13,2k 4 9
0
Mit Marshal haben wir das bisher nicht hinbekommen, also von Hand... hier ein Auszug aus unserem Code.
Bei den CallingConventions etwas aufpassen, wie die C-Funktion deklariert ist.
Hier:
extern "C"  __declspec(dllexport) char * NeSoundGetSoundDeviceNamePlay(UINT uDeviceID);

C# verwendet char (wg. Unicode, MultiByteChar etc.) anders, daher in C# als byte*

// NeSoundGetSoundDeviceNamePlay() ist char *
[DllImport("NESoundBase.dll", CallingConvention = CallingConvention.Cdecl]
static extern unsafe byte* NeSoundGetSoundDeviceNamePlay(uint uDeviceID);

static public unsafe string GetSoundDeviceNamePlay(uint uDeviceID)
{
return getStringFromBytePtr(NeSoundGetSoundDeviceNamePlay(uDeviceID));
}

static private unsafe string getStringFromBytePtr(byte* pb)
{
string s = "";

for (int i = 0; pb[i] != 0; ++i)
{
s += (char)pb[i];
}
return s;
}
01.06.2011
KN 1,7k 1 8

Stelle deine Programmieren-Frage jetzt!