Я пытаюсь передать строку из C # в C ++, используя платформу вызова.
Код C ++:
#include<string>
using namespace std;
extern "C"{
double __declspec(dllexport) Add(double a, double b)
{
return a + b;
}
string __declspec(dllexport) ToUpper(string s)
{
string tmp = s;
for(string::iterator it = tmp.begin();it != tmp.end();it++)
(*it)-=32;
return tmp;
}
}
Код C #:
[DllImport("TestDll.dll", CharSet = CharSet.Ansi, CallingConvention =CallingConvention.Cdecl)]
public static extern string ToUpper(string s);
static void Main(string[] args)
{
string s = "hello";
Console.WriteLine(Add(a,b));
Console.WriteLine(ToUpper(s));
}
Я получаю исключение SEHException. Это невозможно использовать std::string
как это? Должен ли я использовать char*
вместо?
Я предлагаю использовать char *. Здесь возможное решение.
Если вы создадите другую функцию C # ToUpper_2 следующим образом
Сторона C #:
[DllImport("TestDll.dll"), CallingConvention = CallingConvention.Cdecl]
private static extern IntPtr ToUpper(string s);
public static string ToUpper_2(string s)
{
return Marshal.PtrToStringAnsi(ToUpper(string s));
}
Сторона C ++:
#include <algorithm>
#include <string>
extern "C" __declspec(dllexport) const char* ToUpper(char* s)
{
string tmp(s);
// your code for a string applied to tmp
return tmp.c_str();
}
вы сделали!
Правильное решение
Сторона C #:
[DllImport("CppDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr GetString(string s);
public string GetString_(string s)
{
var ptr = GetString(s);
var answerStr = Marshal.PtrToStringAnsi(ptr);
return answerStr;
}
Сторона C ++:
extern "C" __declspec(dllexport) const char* GetString(char* s)
{
string workStr(s);
int lenStr = workStr.length() + 1;
char* answer = new char[lenStr];
const char * constAnswer = new char[lenStr];
strcpy(answer, workStr.c_str());
constAnswer = answer;
return constAnswer;
}
И отключить / sdl- в настройках проекта cpp.