У меня есть часть кода, и я хотел бы знать, правильно это или нет:
hello.cpp
static const char _someGlovalVar[] = "my persistant gloval variable";
const char* DLLInterfaceGetName()
{
return _someGlovalVar;
}
hello.h
DLL_EXPORT const char* DLLInterfaceGetName();
Hello.cs
[DllImport("hello.dll", EntryPoint = "DLLInterfaceGetName", CharSet = CharSet.Ansi)]
public static extern string DLLInterfaceGetName();
Это верно?
Измените возвращаемое значение на IntPtr вместо строки.
[DllImport("hello.dll", EntryPoint = "DLLInterfaceGetName", CharSet = CharSet.Ansi)]
public static extern IntPtr DLLInterfaceGetName();
Затем, когда вы вызываете его в коде С#, переместите указатель в строку С#:
IntPtr cstr = DLLInterfaceGetName();
String str = Marshal.PtrToStringAnsi(cstr);
Кроме того, дважды проверьте, что вы используете соглашение о правом вызове в DLLImport. У меня была проблема, потому что она использует StdCall по умолчанию, и я действительно хотел Cdecl.
Это работает? В этом случае, я не думаю, что вы должны заботиться о чем-то еще :)
Хотя лично я немного обеспокоен тем, как это обрабатывается. Статический указатель const char [], вероятно, находится в разделе кода, не так ли? Надеюсь,.NET marshaller копирует данные в строке в свою собственную строку. Я не уверен, как сторона CPP справляется с этим - возможно ли, что разные компиляторы могут производить значительно разные результаты?
А также, не следует ли положить \0
в конце строки? Как вызывающий абонент знает, как долго строка с помощью char[]
? Я думаю, что если это не сработает для вас, это причина.
id
должен быть либо добавлен в ваше объявление и определение C ++DLLInterfaceGetName
либо удален из вашего объявления C #.