12.03.2010, 14:39
Liebe LeserInnnen,
meine Aufgabe ist es, eine Wrapper-DLL für LV 7.1 zu erstellen. Mein Problem ist die Übergabe von Strings.
Die DLL (VC++ 2008) stellt folgende Funktion bereit:
<blockquote>extern "C" CZPLSDLL_API long WINAPI get_ComponentNames (LPCSTR sCalibFile,
long nExperiment, long nComponent, LPSTR sComponent, long *nComponentSize)
{
<blockquote>[...]
char nstring[100];
[...]
size_t origsize = strlen(nstring);
origsize = min(100,origsize);
memcpy(sComponent,nstring,origsize);
memcpy(sComponent+origsize,"",1);
*nComponentSize = origsize;
return 0;
</blockquote>
}
</blockquote>
Compiler-Einstellungen:
- __stdcall
- /clr (weil gewrappte DLL in C# geschrieben ist)
- /Zp1 (Ausrichten Strukturmember: 1 Byte)
Das Problem:
Wenn ich hinter char nstring[100]; nstring wie folgt deklariere
<blockquote> char nstring[100];
strcpy(nstring,"asdh");
</blockquote>
übernimmt LabVIEW den String korrekt. Wenn ich den String aus meiner gewrappten DLL fülle z.B.
<blockquote> char nstring[100];
String ^str = prd.getString(0);
pin_ptr<const wchar_t> wch = PtrToStringChars(str);
// Convert to a char*
const size_t newsize = 100;
WideCharToMultiByte(CP_ACP, 0, wch, -1, nstring, 100, NULL, NULL);
</blockquote>
(das Ganze liest einen String aus der gemanageden C#-DLL ein, kodiert ihn auf ASCII um und schreibt ihn nach nstring), dann zeigt LabVIEW nur Müll an.
Wenn ich die Wrapper-DLL aus einen VC++-Programm aus aufrufe, kann ich in beiden Varianten der String-Deklaration die Strings korrekt auslesen.
In beiden Varianten der String-Deklaration ist die Stringlänge korrekt, d.h.
<blockquote> sprintf(nstring,"Laenge %d", strlen(nstring));
</blockquote>
liefert die korrekten Werte an LabVIEW und mein VC++-Programm.
Ich habe das Gefühl, es könnte etwas mit UNICODE und ASCII zu tun haben. Nach Lesen des DLL-Tutorials und 3 Jahren Forums-Einträgen, sowie Stunden der alternativen Deklaration (std:string, Cstr, strcpy, memcpy, ...) erlaube ich mir die Frage hier zu stellen.
Ich habe z.Z. keinen Zugriff auf den LV-Code.
Danke
Peter Tillmann
meine Aufgabe ist es, eine Wrapper-DLL für LV 7.1 zu erstellen. Mein Problem ist die Übergabe von Strings.
Die DLL (VC++ 2008) stellt folgende Funktion bereit:
<blockquote>extern "C" CZPLSDLL_API long WINAPI get_ComponentNames (LPCSTR sCalibFile,
long nExperiment, long nComponent, LPSTR sComponent, long *nComponentSize)
{
<blockquote>[...]
char nstring[100];
[...]
size_t origsize = strlen(nstring);
origsize = min(100,origsize);
memcpy(sComponent,nstring,origsize);
memcpy(sComponent+origsize,"",1);
*nComponentSize = origsize;
return 0;
</blockquote>
}
</blockquote>
Compiler-Einstellungen:
- __stdcall
- /clr (weil gewrappte DLL in C# geschrieben ist)
- /Zp1 (Ausrichten Strukturmember: 1 Byte)
Das Problem:
Wenn ich hinter char nstring[100]; nstring wie folgt deklariere
<blockquote> char nstring[100];
strcpy(nstring,"asdh");
</blockquote>
übernimmt LabVIEW den String korrekt. Wenn ich den String aus meiner gewrappten DLL fülle z.B.
<blockquote> char nstring[100];
String ^str = prd.getString(0);
pin_ptr<const wchar_t> wch = PtrToStringChars(str);
// Convert to a char*
const size_t newsize = 100;
WideCharToMultiByte(CP_ACP, 0, wch, -1, nstring, 100, NULL, NULL);
</blockquote>
(das Ganze liest einen String aus der gemanageden C#-DLL ein, kodiert ihn auf ASCII um und schreibt ihn nach nstring), dann zeigt LabVIEW nur Müll an.
Wenn ich die Wrapper-DLL aus einen VC++-Programm aus aufrufe, kann ich in beiden Varianten der String-Deklaration die Strings korrekt auslesen.
In beiden Varianten der String-Deklaration ist die Stringlänge korrekt, d.h.
<blockquote> sprintf(nstring,"Laenge %d", strlen(nstring));
</blockquote>
liefert die korrekten Werte an LabVIEW und mein VC++-Programm.
Ich habe das Gefühl, es könnte etwas mit UNICODE und ASCII zu tun haben. Nach Lesen des DLL-Tutorials und 3 Jahren Forums-Einträgen, sowie Stunden der alternativen Deklaration (std:string, Cstr, strcpy, memcpy, ...) erlaube ich mir die Frage hier zu stellen.
Ich habe z.Z. keinen Zugriff auf den LV-Code.
Danke
Peter Tillmann