How to call VB.NET DLL from C++ (Call the functions also - not DLL file only)

Hadi Al-Zaabi picture Hadi Al-Zaabi · May 13, 2011 · Viewed 9.4k times · Source

I want to ask question about how to call VB.NET DLL from C++ program

I have tried many times to call VB.NET DLL file from C++ and it is working fine but the problem is I can't call the function of VB.NET DLL file ( I can only load the VB.NET DLL file)

in VB.NET DLL I have the following code:

Public Function example_function1(ByVal i As Integer) As Integer
    Return 3

End Function

Public Function example_function2(ByVal i As Integer) As Integer
    Return 3
End Function

============================

My C++ Code is:

    typedef int (__stdcall *ptf_test_func_1_type)(int); 
typedef int (__stdcall *ptf_test_func_2_type)(int*); 
int i =1;

HINSTANCE dll_instance = LoadLibrary("DLLs7.dll");

int main()
{

    if(dll_instance !=NULL)
        {
            printf("The DLLs file has been Loaded \n");
            cout << GetLastError() << endl;

            ptf_test_func_1_type p_func1=(ptf_test_func_1_type)GetProcAddress(dll_instance,"Class1::example_function1");
            ptf_test_func_2_type p_func2=(ptf_test_func_2_type)GetProcAddress(dll_instance,"Class1::example_function2");


            // Function No 1 //

                        if (p_func1 != NULL)
                                 {
                                     cout << "\nThe function number 1 is " << p_func1(i) << endl;

                                }

                        else
                                {
                                    cout << "\nFailed" << endl;
                                    cout << GetLastError() << endl;
                                }

            // Function No 2 //

                        if (p_func2 != NULL)
                                 {
                                     cout << "\nThe function number 2 is" << p_func2(&i) << endl;

                                }

                        else
                                {
                                    cout << "\nFailed" << endl;
                                    cout << GetLastError() << endl;
                                }

        }   
    else
        {
            printf("\nDLLs file Load Error");
            cout << GetLastError() << endl;
        }

        cout << GetLastError() << endl;

    return(0);
}

My following steps is:

1) I have Created VB.NET DLL.

2) I have Created a new application visual C++ and selected "win32 console application"

3) I have written the code to call the DLL and the functions (as you can see in the above)

did I miss anything in the steps or code because I can call VB.NET DLL file but I can't call the VB.NET DLL function

as you can see I have written the GETLASTERRIR() to find the ERROR

cout << GetLastError() << endl;

but I found this Error 127 in function when failed and 203 in the call DLL file

can anyone help me

Thank you very much

Regards

Answer

xtofl picture xtofl · May 13, 2011

Since your vb assembly needs a totally different runtime than the 'native' executable, you will need to use some layer in between. This layer may be COM.

You can expose your assembly to the COM subsystem by it's 'ComVisible' property. Then, you should register the assembly to expose it to COM 'subscribers'.

Only then you can #import the assembly namespace from your c++ code.

Note: this is a very brief version of an msdn article "How to call a managed DLL from native Visual C++ code"

EDIT-- Just tried it out... and it seems to work allright:

C# code

namespace Adder
{
    public interface IAdder
    {
        double add(double a1, double a2);
    }
    public class Adder : IAdder
    {
        public Adder() { }
        public double add(double a1, double a2) { return a1 + a2; }
    }
}

Project settings

[assembly: ComVisible(true)]
[assembly: AssemblyDelaySign(false)]

(Signing was needed in order to be able to generate the tlb)

C++ code:

#import <adder.tlb> raw_interfaces_only

  CoInitialize(NULL);
  Adder::IAdderPtr a;
  a.CreateInstance( __uuidof( Adder::Adder ) );
  double d = 0;
  a->add(1.,1., &d); 
  // note: the method will return a HRESULT; 
  // the output is stored in a reference variable.
  CoUninitialize();