extern "C" __declspec(dllexport) LPSTR Get_GetDescription(HANDLE)
Возвращать такой указатель довольно опасно, так как неясно, кто владеет памятью и, следовательно, кто должен нести ответственность за ее освобождение.
Было бы безопаснее создать буфер в вашемVB-код и передать его в DLL, где значение может быть записано в memcpy. Таким образом, мы можем переписать сторону C ++, например:
extern "C" __declspec(dllexport) void Get_GetDescription(HANDLE, LPSTR)
void Get_GetDescription(HANDLE resultBreakDown, LPSTR buffer){
memcpy(buffer,
((CalcBreakDown*)resultBreakDown)->GetDescription().c_str(),
((CalcBreakDown*)resultBreakDown)->GetDescription().length()+1);
}
, а затем повторить код VB следующим образом:
<DllImport("FeeEngineDll.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Cdecl)> _
Public Shared Sub Get_GetDescription(ByVal resultBreakDown As IntPtr, <MarshalAs(UnmanagedType.LPStr)> ByVal szFilename As StringBuilder)
End Sub
Я добавил CharSet:=CharSet.Ansi
в DllImport.Ваш код C ++ не использует символы Юникода, тогда как VB, вероятно, будет, поэтому лучше указать, что вам, вероятно, не нужно его вставлять, но я хотел бы сделать эти вещи явными.
Обратите внимание на использование StringBuilder
вместо String
, поскольку строки неизменяемы в VB.Наконец, вам нужно быть осторожным, чтобы выделить достаточно места в строителе строк для описания:
Dim buffer As StringBuilder = New StringBuilder(512)
Вы можете сделать это, используя большое число в своем VB-коде, как я только что сделал.Это, однако, вызовет проблемы, если ваш код C ++ когда-либо скопирует больше символов, чем выделено.
Другими лучшими вариантами будет либо передача размера буфера в код C ++, чтобы он знал, сколько ему разрешенонаписать или иметь функцию get size в коде C ++, которая может использоваться для определения того, сколько места должно быть выделено для буфера.