简体   繁体   中英

How to pass a String to const char * from VB.NET to a DLL programmed in C++

I have created a C++ exported function this way:

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)

On the other hand, I have a VB.NET program that uses that C++ function. I have declared it this way:

<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

The calling works and I can debug both the VB.NET program and the C++ function.

When debugging, I realized that the strings are not correctly passed. They are actually passed as garbage. For example, the first parameter:

C ++导出功能

The actual call is:

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

As you see, first parameter is sTelefono and it does contain a value to be passed.

Any help to solve this problem will be appreciated

You must remove the ByRef declaration in your VB.NET code, and just pass string parameters like this:

Function AlmacenarPedidoLipigas(<MarshalAs(UnmanagedType.LPStr)> telefono As String,
...

Passing ByRef can be useful for inout-output parameters, ie the callee can modify the parameter and these modifications are reflected to the caller, which is not the case here. (Moreover, such parameters tend to require an additional level of pointer indirection in C/C++.)

Note also that the conversion from .NET Unicode strings to "ANSI" strings can be lossy; you may want to use const wchar_t* in C++ for Unicode UTF-16 strings, and <MarshalAs(UnmanagedType.LPWStr)> in VB.NET.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM