如何将 String 传递给 const char * 从 VB.NET 到用 C++ 编程的 DLL
How to pass a String to const char * from VB.NET to a DLL programmed in C++
我用这种方式创建了一个 C++ 导出函数:
extern "C" __declspec(dllexport)
int __stdcall AlmacenarPedidoLipigas(const char * pszTelefono, const char * pszFechaPedido, const char * pszHoraPedido, const char * pszCodigoInterno, const char * pszDescripcionProducto,
const char * pszCantidadProducto, const char * pszValorUnitario, const char * pszFechaEntrega, const char * pszHoraEntrega, const char * pszKilosProducto,
const char * pszFechaDespacho, const char * pszHoraDespacho)
另一方面,我有一个使用该 C++ 函数的 VB.NET 程序。我是这样声明的:
<DllImport("ComTest.dll", CharSet:=CharSet.Ansi)>
Function AlmacenarPedidoLipigas(<MarshalAs(UnmanagedType.LPStr)> ByRef pszTelefono As String,
<MarshalAs(UnmanagedType.LPStr)> ByRef pszFechaPedido As String, <MarshalAs(UnmanagedType.LPStr)> ByRef pszHoraPedido As String,
<MarshalAs(UnmanagedType.LPStr)> ByRef pszCodigoInterno As String, <MarshalAs(UnmanagedType.LPStr)> ByRef pszDescripcionProducto As String,
<MarshalAs(UnmanagedType.LPStr)> ByRef pszCantidadProducto As String, <MarshalAs(UnmanagedType.LPStr)> ByRef pszValorUnitario As String,
<MarshalAs(UnmanagedType.LPStr)> ByRef pszFechaEntrega As String, <MarshalAs(UnmanagedType.LPStr)> ByRef pszHoraEntrega As String,
<MarshalAs(UnmanagedType.LPStr)> ByRef pszKilosProducto As String,
<MarshalAs(UnmanagedType.LPStr)> ByRef pszFechaDespacho As String, <MarshalAs(UnmanagedType.LPStr)> ByRef pszHoraDespacho As String) As UInt16
调用有效,我可以同时调试 VB.NET 程序和 C++ 函数。
调试时,发现字符串没有正确传递。它们实际上是作为垃圾传递的。比如第一个参数:
实际调用是:
Sub Main()
Dim sTelefono As String = "229188562"
Dim sFechaPedido As String = "16/12/2016"
Dim sHoraPedido As String = "20:30"
Dim sCodigoInterno As String = "123456"
Dim sDescripcionProducto As String = "CARGA CODIGAS CATALITICO 15 KILOS"
Dim sCantidadProducto As String = "2"
Dim sValorUnitario As String = "14000"
Dim sFechaEntrega As String = "19/12/2016"
Dim sHoraEntrega As String = "15:14"
Dim sKilosProducto As String = "15"
Dim sFechaDespacho As String = "19/12/2016"
Dim sHoraDespacho As String = "10:00"
Dim iPedido As Integer = AlmacenarPedidoLipigas(sTelefono, sFechaPedido, sHoraPedido, sCodigoInterno, sDescripcionProducto, sCantidadProducto, sValorUnitario, sFechaEntrega, sHoraEntrega, sKilosProducto, sFechaDespacho, sHoraDespacho)
Console.WriteLine(iPedido)
End Sub
如您所见,第一个参数是 sTelefono,它确实包含要传递的值。
任何解决此问题的帮助将不胜感激
您必须删除 VB.NET 代码中的 ByRef
声明,并像这样传递字符串参数:
Function AlmacenarPedidoLipigas(<MarshalAs(UnmanagedType.LPStr)> telefono As String,
...
传递ByRef
对于inout输出参数很有用,即被调用者可以修改参数并且这些修改会反映给调用者,这里不是这种情况。 (此外,此类参数在 C/C++ 中往往需要额外的指针间接级别。)
另请注意,从 .NET Unicode 字符串到 "ANSI" 字符串的转换可能是有损的;对于 Unicode UTF-16 字符串,您可能希望在 C++ 中使用 const wchar_t*
,在 VB.NET.
中使用 <MarshalAs(UnmanagedType.LPWStr)>
我用这种方式创建了一个 C++ 导出函数:
extern "C" __declspec(dllexport)
int __stdcall AlmacenarPedidoLipigas(const char * pszTelefono, const char * pszFechaPedido, const char * pszHoraPedido, const char * pszCodigoInterno, const char * pszDescripcionProducto,
const char * pszCantidadProducto, const char * pszValorUnitario, const char * pszFechaEntrega, const char * pszHoraEntrega, const char * pszKilosProducto,
const char * pszFechaDespacho, const char * pszHoraDespacho)
另一方面,我有一个使用该 C++ 函数的 VB.NET 程序。我是这样声明的:
<DllImport("ComTest.dll", CharSet:=CharSet.Ansi)>
Function AlmacenarPedidoLipigas(<MarshalAs(UnmanagedType.LPStr)> ByRef pszTelefono As String,
<MarshalAs(UnmanagedType.LPStr)> ByRef pszFechaPedido As String, <MarshalAs(UnmanagedType.LPStr)> ByRef pszHoraPedido As String,
<MarshalAs(UnmanagedType.LPStr)> ByRef pszCodigoInterno As String, <MarshalAs(UnmanagedType.LPStr)> ByRef pszDescripcionProducto As String,
<MarshalAs(UnmanagedType.LPStr)> ByRef pszCantidadProducto As String, <MarshalAs(UnmanagedType.LPStr)> ByRef pszValorUnitario As String,
<MarshalAs(UnmanagedType.LPStr)> ByRef pszFechaEntrega As String, <MarshalAs(UnmanagedType.LPStr)> ByRef pszHoraEntrega As String,
<MarshalAs(UnmanagedType.LPStr)> ByRef pszKilosProducto As String,
<MarshalAs(UnmanagedType.LPStr)> ByRef pszFechaDespacho As String, <MarshalAs(UnmanagedType.LPStr)> ByRef pszHoraDespacho As String) As UInt16
调用有效,我可以同时调试 VB.NET 程序和 C++ 函数。
调试时,发现字符串没有正确传递。它们实际上是作为垃圾传递的。比如第一个参数:
实际调用是:
Sub Main()
Dim sTelefono As String = "229188562"
Dim sFechaPedido As String = "16/12/2016"
Dim sHoraPedido As String = "20:30"
Dim sCodigoInterno As String = "123456"
Dim sDescripcionProducto As String = "CARGA CODIGAS CATALITICO 15 KILOS"
Dim sCantidadProducto As String = "2"
Dim sValorUnitario As String = "14000"
Dim sFechaEntrega As String = "19/12/2016"
Dim sHoraEntrega As String = "15:14"
Dim sKilosProducto As String = "15"
Dim sFechaDespacho As String = "19/12/2016"
Dim sHoraDespacho As String = "10:00"
Dim iPedido As Integer = AlmacenarPedidoLipigas(sTelefono, sFechaPedido, sHoraPedido, sCodigoInterno, sDescripcionProducto, sCantidadProducto, sValorUnitario, sFechaEntrega, sHoraEntrega, sKilosProducto, sFechaDespacho, sHoraDespacho)
Console.WriteLine(iPedido)
End Sub
如您所见,第一个参数是 sTelefono,它确实包含要传递的值。
任何解决此问题的帮助将不胜感激
您必须删除 VB.NET 代码中的 ByRef
声明,并像这样传递字符串参数:
Function AlmacenarPedidoLipigas(<MarshalAs(UnmanagedType.LPStr)> telefono As String,
...
传递ByRef
对于inout输出参数很有用,即被调用者可以修改参数并且这些修改会反映给调用者,这里不是这种情况。 (此外,此类参数在 C/C++ 中往往需要额外的指针间接级别。)
另请注意,从 .NET Unicode 字符串到 "ANSI" 字符串的转换可能是有损的;对于 Unicode UTF-16 字符串,您可能希望在 C++ 中使用 const wchar_t*
,在 VB.NET.
<MarshalAs(UnmanagedType.LPWStr)>