2

EDIT 5

I have erased the previous post, since the code has been fully changed (hoping no rules violation).

I removed all previous references to problematic String variables.

Now the question:

For study purposes, I have made my first very simple Visual C++ DLL, and I want to use it in VB.Net.

In addition to the auto-generated files from Visual C++ (dllmain.cpc, pch.h, pch.cpp, to which I added my code.h) I have added two files to define my function:

code.h

#pragma once
#include "pch.h"

#ifndef ADD_CODE_H
#define ADD_CODE_H
//extern "C"
//{
   __declspec(dllexport) int add_code(int lng);
//}
#endif

code.cpp

#include <iostream>
#include "pch.h"
#include "code.h"

int add_code(int lng) {

    switch (lng) {
    case 4:
        return 1;
    case 5:
        return 2;
    default:
        return 9;
    }

    return 0;

}

No errors compiling the Visual C++ code. Tried both x86 and x64.

If I uncomment "Extern C"" by microsoft Dumper I get:

1    0 00001000 ?add_code@@YAHH@Z = ?add_code@@YAHH@Z (int __cdecl add_code(int))

If I comment it I obtain:

1    0 00001000 add_code = _add_code

From VB.NET, I try to call the DLL with this code:

vb.net

<DllImport("MyDll.dll", EntryPoint:="add_code@@YAHH@Z")> 'also "?add_code@@YAHH@Z"
'Also "CallingConvention: = CallingConvention.Cdecl
   Public Shared Function add_code(ByVal lng As Integer) As Integer
End Function

And also:

<DllImport("MyDll.dll", EntryPoint:="_add_code")> ' Also "CallingConvention: = CallingConvention.Cdecl
     Public Shared Function add_code(ByVal lng As Integer) As Integer  'Also "_add_code"
End Function

VB Main:

Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load

  Dim foo As Integer = add_code(4) 'Also "_add_code"

End Sub

Tried both x86 (dll x86), x64 (dll x64) and Any Cpu (both dll x86 or x64).

I always get the error:

System.EntryPointNotFoundException: Could not find entry point with name 'add_code' in MyDll.dll

12
  • 3
    You cannot pass a std::string to/from managed code. Either use c++/cli in the middle, or for PInvoke you need to use a compatible string. Commented Oct 20 at 15:19
  • Whatever is saying that extern "C" is incompatible with stdcall is confused, possibly it's trying to highlight the conflict with having a std::string as an argument, stdcall itself most certainly is compatible with extern "C". But note that stdcall is only meaningful in 32-bit code, there is only one calling convention in 64-bit. Commented Oct 20 at 15:43
  • @ craig: If I uncomment "extern C" debug compiler says: "warning C4190: for 'add_code' C binding was specified, but it returns the user-defined type 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>', which is incompatible with C" Commented Oct 20 at 16:07
  • @wohlstand: but the current error don't warns incompatible variable declarations, but Entry Point Not Found. Commented Oct 20 at 16:14
  • 1
    @eziog. Yes, as I thought, the issue with extern "C" isn't with stdcall, it's with std::string. Commented Oct 21 at 14:18

1 Answer 1

6

Read up about "name mangling" (aka "name decoration"). And look at the actual EXPORTS table of your DLL. Your DLL function is not being exported as add_code like you are expecting, which is why VB can't find it. The function is actually being exported more like _add_code@4 instead (or _add_code if you remove the string usage so that extern "C" will work).

If you want the function to export exactly as add_code then you need to use a .DEF file to define that behavior, see Exporting from a DLL Using DEF Files on MSDN for details.

Also, std::string is not an interop-safe type that is compatible with VB (or most other languages, for that matter), so you can't use it in your DLL function's interface. See Marshalling Strings and Default marshalling for strings on MSDN for detail on how to use string-safe operations with PInvoke.

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

Comments

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.