Frage

Ich habe Probleme, eine Zeichenfolge zurück von einem C-Code immer ich geschrieben habe.

Zuerst einige allgemein unrealated Hintergrundinformationen: Ich möchte den Benutzer lesbare Zeichenfolge für eine TAPI TSP von der TAPI-API erhalten. Ich habe eine halb bearbeitbar TAPI-Lösung unter Berufung auf passende Treibernamen zu gespeicherten Strings implementiert, möchte aber, dies ändern, anstatt auf permanant Linie ids zu arbeiten, als einer unserer Kunden hat einen (Alcatel) PBX, das jede andere Art und Weise zu arbeiten, verweigert .

In C definiere ich die Funktion in meiner Header-Datei wie:

__declspec(dllexport) void GetDeviceName(long DeviceId, wchar_t* DeviceName);

Die Funktion wird geschrieben thusly:

__declspec(dllexport) void GetDeviceName(long DeviceId, wchar_t* DeviceName)
{
    //tapi code here...

    //copy the string to DeviceName
    wcscpy(DeviceName, (wchar_t*)((char *)devCaps + devCaps->dwLineNameOffset));
}

Wie bereits erwähnt, wird dies schließlich etwas Sinnvolles tun, aber jetzt werde ich glücklich sein, wenn abc in meinem wchar_t * / String platziert ist und das kann ich in C # sehen.

In C # definiere ich die Funktion als:

    [DllImport("SBW.Tapi.TapiInterop.dll", CharSet = CharSet.Auto)]
    static extern void GetDeviceName(long DeviceId, StringBuilder DeviceName);

Ich definiere Device als String weil ein String immuatable ist, und ich möchte, dass die Device in C eingestellt werden ( Dies wird durch MS ) empfohlen. Ich habe auch den Rückgabetyp auf der vagen Hoffnung auf void dass das wirkt sich auch etwas (siehe dieser halb~~POS=TRUNC hilfreich Mono Artikel für eine teilweise pseudo wissenschaftliche Erklärung).

Und nennen Sie es so:

StringBuilder name = new StringBuilder();
name.EnsureCapacity(100);
long n = 0;
GetDeviceName(n, name);

Ich lege meinen Debugger an dem laufenden Prozess, einen Haltepunkt, und Bekanntmachung im C-Code, der irgendwie der String pervertiert ist und an den nicht verwalteten Code als Null-Zeiger zur Verfügung gestellt.

Ein Access anschließend in C # geworfen wird.

Was schief gegangen ist?

Entfernen der lange Parameter hilft. Ich bin in der Lage „abc“ zu meinen Device Parameter in C. Ich möchte, dass lange Variable jedoch hinzuzufügen! Was mache ich falsch oder Stauchen zu tun, um einen Absturz zu erzwingen, indem es diesen langen Parameter mit?

War es hilfreich?

Lösung

Ein 32 Bit-Plattformen long ist 8 Bytes (64 Bits) breit in .NET und 4 Bytes (32 Bits) breit in nativen Code. Sie benötigen eine P / Invoke Methode wie folgt zu ändern:

[DllImport("SBW.Tapi.TapiInterop.dll", CharSet = CharSet.Auto)]
static extern void GetDeviceName(int DeviceId, StringBuilder DeviceName);

Auf diese Weise C # int und C long haben die gleiche Breite auf 32-Bit-Plattformen.

Andere Tipps

  

Ich möchte, dass lange Variable jedoch

Dann sollten Sie die Parameter in C als long long definieren. Wie Lucero erwähnt, ist eine lange in C ++ 32 Bits, während eine lange in C # 64 Bits. Also, wenn Sie eine 64-Bit-Wert übergeben, wo die C-Funktion über einen 32-Bit-Wert erwartet, liest die Funktion die zusätzlichen 32 Bits als zweiten Parameter, der offensichtlich in einer falschen Adresse ergibt sich für den Puffer ...

Die C ++ long ist 32 Bits, die C # long 64 Bits ist, ist es nicht? Daher müssen Sie eine int für den ersten Parameter verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top