Reputation: 2890
I have a problem which I just can't figure out. I'm trying to call a member function of a C++ class from VB.Net by using a wrapper function, and passing a pointer to this wrapper function.
C++:
class _declspec(dllexport) MyClass{
public:
int multiply(int x, int y) const;
char* get_name() const;
};
_declspec(dllexport) void* createMyClass();
_declspec(dllexport) void destroyMyClass(void* objptr);
_declspec(dllexport) int MyClass_multiply(void* objptr, int x, int y);
The definitions are:
int MyClass::multiply(int x, int y) const
{
return x * y;
}
char* MyClass::get_name() const
{
return "jensa";
}
void* createMyClass()
{
return new MyClass;
}
void destroyMyClass(void* objptr)
{
delete static_cast<MyClass*>(objptr);
}
int MyClass_multiply(void* objptr, int x, int y)
{
std::ofstream fout("jojo.txt", std::ios::out);
fout << x << std::endl;
fout << y << std::endl;
MyClass* p = (MyClass*)(objptr); // Explicit type cast
fout << p->get_name() << std::endl;
fout.close();
return p->multiply(x,y);
}
I use the ofstream just for checking what the arguments actually are inside the C++ function MyClass_multiply. If I call the function from VB.Net like this
<DllImport(Constants.DLL_PATH, EntryPoint:="MyClass_multiply", CallingConvention:=CallingConvention.Cdecl)>
Private Shared Function MyClass_multiply(ByVal objptr As Long, ByVal x As Long, ByVal y As Long) As Long
End Function
Dim objptr As Long = createMyClass()
Me.TextBox3.Text = MyClass_multiply(objptr, 2, 3)
I find that the first integer argument in the C++ function MyClass_multiply, x, becomes some strange value like 63203420, and the argument y takes on the value which x was set to. When I created a similar function add in my C++ dll, which only took two integers and no void*, everything worked fine. Am I doing something wrong with the void*? (Note: I'm using http://www.codeproject.com/Articles/6244/Step-by-Step-Calling-C-DLLs-from-VC-and-VB-Part).
Thank you!
Edit: I am using a .def file.
LIBRARY MyLib.dll
EXPORTS
add
createMyClass
destroyMyClass
MyClass_multiply
Upvotes: 0
Views: 973
Reputation: 2890
It seems to be working now. I changed all occurences of
objptr As Long
to
objPtr As IntPtr
per your suggestion. I also noticed that I needed all the other variables (x and y in the MyClass_multiply function) to be of type Integer, NOT Long). That is,
<DllImport(Constants.DLL_PATH, EntryPoint:="MyClass_multiply", CallingConvention:=CallingConvention.Cdecl)>
Private Shared Function MyClass_multiply(ByVal objptr As IntPtr, ByVal x As Integer, ByVal y As Integer) As Integer
End Function
Just to be clear: Just as you suggested I needed to make ALL other types Integers. Having function arguments as Integer and the return value Long did not work. Having Long function arguments but Integer return value did not work either. Hopefully this could help others in a similar situation! Thanks!
Upvotes: 0
Reputation: 3670
Private Shared Function MyClass_multiply(ByVal objptr As IntPtr, ByVal x As Integer, ByVal y As Integer) As Integer
End Function
If you have many codes of native that should be p/invoked you can try tool. It generaes for both c# and VB.Net
Upvotes: 1