从VB.NET调用C ++函数时AccessViolationException

时间:2016-12-19 03:12:11

标签: c++ vb.net dllimport dllexport

我用C ++创建了一个带有一个导出函数的DLL,这样:

extern "C" __declspec(dllexport) int __stdcall AlmacenarPedido(DWORD dwTelefono, LPCTSTR lpszFechaPedido, LPCTSTR lpszHoraPedido, LPCTSTR lpszCodigoInterno, LPCTSTR lpszDescripcionProducto,
                                          int iCantidadProducto, int iValorUnitario, LPCTSTR lpszFechaEntrega, LPCTSTR lpszHoraEntrega, int iKilosProducto, 
                                          LPCTSTR lpszFechaDespacho, LPCTSTR lpszHoraDespacho)

我试图从VB.NET调用这个函数。

这是DllImport:

<DllImport("ComTesting.dll", CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.StdCall)>
Function AlmacenarPedido(ByVal dwTelefono As Long, ByVal lpszFechaPedido As String, ByVal lpszHoraPedido As String,
                         ByVal lpszCodigoInterno As String, ByVal lpszDescripcionProducto As String,
                         ByVal iCantidadProducto As Integer, ByVal iValorUnitario As Integer, ByVal lpszFechaEntrega As String, ByVal lpszHoraEntrega As String,
                         ByVal iKilosProducto As Integer, ByVal lpszFechaDespacho As String, ByVal lpszHoraDespacho As String) As Integer
End Function

这是实际的电话:

Sub Main()
    Dim lTelefono As Long = 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 iCantidadProducto As Integer = 2
    Dim iValorUnitario As Integer = 14000
    Dim sFechaEntrega As String = "19/12/2016"
    Dim sHoraEntrega As String = "15:14"
    Dim iKilosProducto As Integer = 15
    Dim sFechaDespacho As String = "19/12/2016"
    Dim sHoraDespacho As String = "10:00"
    Dim iPedido As Integer = AlmacenarPedido(lTelefono, sFechaPedido, sHoraPedido, sCodigoInterno, sDescripcionProducto, iCantidadProducto, iValorUnitario, sFechaEntrega, sHoraEntrega, iKilosProducto, sFechaDespacho, sHoraDespacho)
    Console.WriteLine(iPedido)
End Sub

调用时,抛出AccessExceptionException。

请帮忙吗?

编辑:

堆栈跟踪:

   en Testing.MainModule.AlmacenarPedido(Int64 dwTelefono, String& lpszFechaPedido, String& lpszHoraPedido, String& lpszCodigoInterno, String& lpszDescripcionProducto, Int32 iCantidadProducto, Int32 iValorUnitario, String& lpszFechaEntrega, String& lpszHoraEntrega, Int32 iKilosProducto, String& lpszFechaDespacho, String& lpszHoraDespacho)
   en Testing.MainModule.Main() en C:\WorkingFolder\Proyectos\Lipigas\GasProvidencia\Testing\MainModule.vb:línea 37
   en System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   en System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   en Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   en System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   en System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   en System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   en System.Threading.ThreadHelper.ThreadStart()

2 个答案:

答案 0 :(得分:4)

我看到了问题。第一个参数dwTelefono在DLL中声明为DWORD,但在Pinvoke声明中声明为Long。 DWORD是32位,VB.NET中的Longs是64位。因此,在调用DLL时,堆栈设置错误。

更改第一个参数声明:

 Function AlmacenarPedido(ByVal dwTelefono As Long,

对此:

Function AlmacenarPedido(ByVal dwTelefono As UInt32,

我在本地对此进行了测试并确认修复了它。

答案 1 :(得分:1)

  1. 关于你的第一个问题:selbie绝对正确。 VB.Net“Long”&lt;&gt; C / C ++“DWORD”。我相信你已经解决了这个问题。

  2. 同样,关于您的第二个问题,String& lpszFechaPedido!= LPCTSTR lpszFechaPedido!您需要<MarshalAs(UnmanagedType.LPStr)return string from c++ function to VB .Net

  3. 请阅读使用VB.Net连接“本机代码” - 这将大大简化您的工作:

    MSDN: Calling Native Functions from Managed Code

    MSDN: Overview of Marshaling in C++