std::string in C#?

Lesezeit: 3 Minuten

Ich dachte, das Problem liegt in meiner C++-Funktion, aber ich habe es versucht

C++-Funktion in C++-DLL:

bool __declspec( dllexport ) OpenA(std::string file)
{
return true;
}

C#-Code:

[DllImport("pk2.dll")]
public static extern bool OpenA(string path);

    if (OpenA(@"E:\asdasd\"))

Ich erhalte eine Ausnahme, dass der Speicher beschädigt ist, warum?

Wenn ich den std::string-Parameter entferne, funktioniert es großartig, aber mit std::string funktioniert es nicht.

  • Vielleicht können Sie es lösen, indem Sie eine verwaltete C++-Brücke erstellen, die die Zeichenfolge entpackt? Hier ist eine SO-Frage zu diesem Thema.

    – FeatureCreep

    17. Mai 2009 um 13:11 Uhr

std::string und c# string sind nicht miteinander kompatibel. Soweit ich weiß, entspricht die c#-Zeichenfolge der Weitergabe char* oder wchar_t* in C++ was Interop betrifft.
Einer der Gründe dafür ist, dass es viele verschiedene Implementierungen für std::string geben kann und c# nicht davon ausgehen kann, dass Sie eine bestimmte verwenden.

  • Ganz zu schweigen davon, dass std::string auch ein Template ist, das eine weitere interessante Wurmkiste für die Interop öffnet.

    – Timo Geusch

    17. Mai 2009 um 13:04 Uhr

  • Der beste Weg ist, char* zu verwenden und daraus std::string zu erstellen. Wenn Sie einen std::string an C# zurückgeben möchten, müssen Sie ein char* mit CoTaskMemAlloc mit der Größe von std::string’s size()+1 zuweisen, dann memcpy std::string’s data() in diesen Puffer einfügen und ihn zurückgeben. Leicht. Hinweis: Sie MÜSSEN CoTaskMemAlloc verwenden!

    – Петър Петров

    10. März 2015 um 0:54 Uhr

Versuchen Sie so etwas:

bool __declspec( dllexport ) OpenA(const TCHAR* pFile)
{ 
   std::string filename(pFile);
   ...
   return true;
}

Außerdem sollten Sie in Ihrem DllImport-Attribut den passenden Zeichensatz (unicode/ansi) angeben.

Abgesehen davon, unabhängig von Ihrem Marshalling-Problem, würde man normalerweise eine std:string als const-Referenz übergeben: const std:string& filename.

  • dass std::string die Kompilierung fehlschlägt, wenn _UNICODE definiert ist. Vielleicht ist es besser, eine #ifdef zu machen und std::wstring zu verwenden oder einfach eine Typedef für eine tstring zu machen, abhängig von _UNICODE.

    – Idan K

    17. Mai 2009 um 16:21 Uhr

Es ist nicht möglich, einen C++ std::string so zu marshallen, wie Sie es versuchen. Was Sie hier wirklich tun müssen, ist eine Wrapper-Funktion zu schreiben, die eine einfache alte verwendet const char* und wird unter der Haube in einen std::string konvertiert.

C++

extern C { 
  void OpenWrapper(const WCHAR* pName) {
    std::string name = pName;
    OpenA(name);
  }
}

C#

[DllImport("pk2.dll")]
public static extern void OpenWrapper( [In] string name);

std::wstring und System.string können durch die folgende Konvertierung kompatibel sein:

C++:

bool func(std::wstring str, int number)
{
  BSTR tmp_str = SysAllocStringLen(str.c_str(), str.size());
  VARIANT_BOOL ret = VARIANT_FALSE;

  // call c# COM DLL
  ptr->my_com_function(tmp_str, number, &ret);

  SysFreeString(tmp_str);

  return (ret != VARIANT_FALSE) ? true : false;
}

Ich weiß, dass dieses Thema ein bisschen alt ist, aber für zukünftige Googler sollte dies auch funktionieren (ohne char* in C++ zu verwenden).

C#:

public static extern bool OpenA([In, MarshalAs(UnmanagedType.LPStr)] path);

C++:

bool __declspec( dllexport ) OpenA(std::string file);

  • Was meinen Sie? Hast du den obigen Code ausprobiert und es hat nicht funktioniert?

    – Nita

    3. März 2015 um 9:45 Uhr

  • Ich meine, gibt es eine Referenzseite, die besagt, dass es funktionieren sollte, und die Anforderungen definiert, damit es funktioniert?

    – Reben

    3. März 2015 um 9:47 Uhr

  • Es tut mir leid, aber ich kann die Referenz für diesen Geldautomaten nicht finden (das ist ziemlich lange her). Sie können jedoch diese Seite ausprobieren: msdn.microsoft.com/en-us/library/s9ts558h%28v=vs.110%29.aspx

    – Nita

    3. März 2015 um 10:49 Uhr

  • Was meinen Sie? Hast du den obigen Code ausprobiert und es hat nicht funktioniert?

    – Nita

    3. März 2015 um 9:45 Uhr

  • Ich meine, gibt es eine Referenzseite, die besagt, dass es funktionieren sollte, und die Anforderungen definiert, damit es funktioniert?

    – Reben

    3. März 2015 um 9:47 Uhr

  • Es tut mir leid, aber ich kann die Referenz für diesen Geldautomaten nicht finden (das ist ziemlich lange her). Sie können jedoch diese Seite ausprobieren: msdn.microsoft.com/en-us/library/s9ts558h%28v=vs.110%29.aspx

    – Nita

    3. März 2015 um 10:49 Uhr

923310cookie-checkstd::string in C#?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy