-2

I created a DLL with one exported function in C++, this way:

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)

I am trying to call this function from VB.NET.

This is the 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

And this is the actual call:

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

When the calling is made, AccessExceptionException is thrown.

Any help, please?

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()
5
  • Show complete stack trace. Commented Dec 19, 2016 at 3:19
  • Added stack trace Commented Dec 19, 2016 at 3:28
  • Show the code to the function exported by your DLL. Also, is your DLL compiled as UNICODE? (Hint: LPCTSTR is ambiguous and causes confusion with regards to charset declaration in .net. Use LPCSTR or LPCWSTR explicitly). Commented Dec 19, 2016 at 3:34
  • i have changed LPCTSTR by LPCWSTR but the same happen. The body of the DLL is not relevant since the exported function is not even called Commented Dec 19, 2016 at 3:43
  • Possible hint: DWORD is 32-bits, your import specifies dwTelefono as Long, shouldn't be Integer? Commented Dec 19, 2016 at 4:06

2 Answers 2

3

I see the problem. The first parameter, dwTelefono, is declared as DWORD in the DLL, but as a Long in the Pinvoke declaration. DWORDs are 32-bit and Longs in VB.NET are 64-bit. Hence, the stack is getting setup wrong when the DLL is invoked.

Change the first parameter declaration from this:

 Function AlmacenarPedido(ByVal dwTelefono As Long,

To this:

Function AlmacenarPedido(ByVal dwTelefono As UInt32,

I tested this out locally and confirmed it fixed it.

Sign up to request clarification or add additional context in comments.

3 Comments

I was just about to point out the same thing. You're exactly right :)
I have tried and it worked, at least I don't have that error anymore, however, strings are not passed correctly. I have defined them as "char *", but only garbage is passed.
Change your charset to: CharSet:=CharSet.Ansi to have pinvoke convert the .net strings to ansi/ascii.
0
  1. Regarding your first problem: selbie is absolutely correct. VB.Net "Long" <> C/C++ "DWORD". I believe you fixed that.

  2. Similarly, regarding your second problem, String& lpszFechaPedido != LPCTSTR lpszFechaPedido! You need <MarshalAs(UnmanagedType.LPStr): return string from c++ function to VB .Net

Please read up on interfacing "Native code" with VB.Net - that will greatly simplify your work:

MSDN: Calling Native Functions from Managed Code

MSDN: Overview of Marshaling in C++

2 Comments

For the second problem, I tried several ways, but with no avail. I have opened a new question with this: stackoverflow.com/questions/41232992/…
If selbie helped, then please accept and upvote his answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.