2016-12-19 18 views
-2

Я создал DLL с одной экспортированной функции в C++, таким образом:AccessViolationException при вызове функции C++ из VB.NET

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 выбрасывается.

Любая помощь, пожалуйста?

EDIT:

StackTrace:

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() 
+0

Показать полный трассировки стека , – OldProgrammer

+0

Добавлена ​​трассировка стека – jstuardo

+0

Показать код функции, экспортируемой вашей DLL. Кроме того, ваша библиотека DLL составлена ​​как UNICODE? (Подсказка: LPC ** T ** STR неоднозначно и вызывает путаницу в отношении объявления charset в .net. Используйте LPCSTR или LPCWSTR явно). – selbie

ответ

4

Я вижу проблему. Первый параметр, dwTelefono, объявлен как DWORD в DLL, но как Long в объявлении Pinvoke. DWORDs - 32-разрядные, а Longs в VB.NET - 64-разрядные. Следовательно, стек вызывает неправильную настройку при вызове DLL.

Изменение первого объявление параметра из этого:

Function AlmacenarPedido(ByVal dwTelefono As Long, 

Для этого:

Function AlmacenarPedido(ByVal dwTelefono As UInt32, 

Я испытал это на местном уровне, и подтвердил, что он установил ее.

+0

Я как раз собирался указать то же самое. Вы точно правы :) – paulsm4

+0

Я пробовал, и это сработало, по крайней мере, у меня больше нет этой ошибки, однако строки не переданы правильно.Я определил их как «char *», но передан только мусор. – jstuardo

+0

Измените свою кодировку на: 'CharSet: = CharSet.Ansi', чтобы pinvoke преобразовал строки .net в ansi/ascii. – selbie

1
  1. Что касается первой проблемы: selbie абсолютно прав. VB.Net "Long" <> C/C++ "DWORD". Полагаю, вы это исправили.

  2. Аналогично, в отношении вашей второй проблемы, String& lpszFechaPedido! = LPCTSTR lpszFechaPedido! Вам нужно <MarshalAs(UnmanagedType.LPStr): return string from c++ function to VB .Net

Пожалуйста, почитайте о взаимодействии "Native код" с VB.Net - что значительно упростит вашу работу:

MSDN: Calling Native Functions from Managed Code

MSDN: Overview of Marshaling in C++

+0

Для второй проблемы я пробовал несколько способов, но безрезультатно. Я открыл новый вопрос: http://stackoverflow.com/questions/41232992/how-to-pass-a-string-to-const-char-from-vb-net-to-a-dll-programmed -in-c – jstuardo

+0

Если бы selbie помог, то, пожалуйста, примите и открепите его ответ. – paulsm4