gpt4 book ai didi

c++ - 从 C++ 函数返回字符串到 VB .Net

转载 作者:太空狗 更新时间:2023-10-29 21:06:12 24 4
gpt4 key购买 nike

我正在尝试从使用 P/Invoke 返回字符串的 VB.Net 代码调用 C++ 函数,但它只返回单个字符。

C函数声明

  extern "C" __declspec(dllexport) LPSTR Get_GetDescription(HANDLE)

C函数定义

  LPSTR Get_GetDescription(HANDLE resultBreakDown){
return LPSTR(((CalcBreakDown*)resultBreakDown)->GetDescription().c_str());
}

VB.Net 代码

    <DllImport("FeeEngineDll.dll", CallingConvention:=CallingConvention.Cdecl)> _
Public Shared Function Get_GetDescription(ByVal resultBreakDown As IntPtr, ByVal indexSubs As Integer, ByVal indexLine As Integer) As <MarshalAsAttribute(LPStr)> String
End Function

返回类型或编码有问题吗?

最佳答案

extern "C" __declspec(dllexport) LPSTR Get_GetDescription(HANDLE)

像这样返回一个指针是相当危险的,因为不清楚谁拥有内存,因此谁应该负责释放它。

在您的 VB 代码中创建缓冲区并将其传递到 DLL 中会更安全,在 DLL 中可以存储值。因此我们可以像这样重写 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++ 代码没有使用 unicode 字符,而 VB 可能会使用,所以最好说明一下,你可能不需要把它放进去,但我喜欢把这些东西明确化。

请注意使用 StringBuilder 而不是 String 因为字符串在 VB 中是不可变的。最后,您需要注意在字符串构建器中为描述分配足够的空间:

Dim buffer As StringBuilder = New StringBuilder(512)

您可以通过在 VB 代码中使用大量数字来完成此操作,就像我刚刚所做的那样。但是,如果您的 C++ 代码复制的字符多于您分配的字符,这将导致问题。

其他更好的选择是将缓冲区大小传递给 C++ 代码,以便它知道允许写入多少,或者在 C++ 代码中使用获取大小函数来确定有多少应为缓冲区分配空间。

关于c++ - 从 C++ 函数返回字符串到 VB .Net,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8049478/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com