Importing Class from C++ dll
Importing Class from C++ dll
Importing Class from C++ dll
Importing Class from C++ dll
Importing Class from C++ dll
Importing Class from C++ dll Importing Class from C++ dll Importing Class from C++ dll Importing Class from C++ dll Importing Class from C++ dll Importing Class from C++ dll Importing Class from C++ dll Importing Class from C++ dll
Importing Class from C++ dll Importing Class from C++ dll
Importing Class from C++ dll
Go Back  Xtreme Visual Basic Talk > > > Importing Class from C++ dll


Reply
 
Thread Tools Display Modes
  #1  
Old 12-10-2011, 04:08 PM
-clueless -clueless is offline
Newcomer
 
Join Date: Jul 2009
Posts: 6
Default Importing Class from C++ dll


Ok, I've been fighting this for days and so far haven't found very much helpful information on the web. Apparently this isn't a very popular thing to do since there isn't much out there. I'm hoping someone here can help me out.

If it's relavent I'm using Visual Studio 2010 on a Windows 7 machine.

I'm working on a much larger project, so I've created a greatly simplified version to test and and ask questions about.

Here's the situation: I've created a class in c++ that I now need to create an interface for in vb.

Question part 1:
Ideally, I wanted to import the entire class into vb so I could do something like:
Code:
Dim myObject As MyDllClass
And then I would be able to access all the member functions/variables of that class from vb like this:
Code:
myObject.mydllclassInsert(data)
myObject.mydllclassSetValue(9)
myObject.mydllclassGetValue()
' etc...
I've been able to find a couple references on the c++/dll side that say you can export an entire class to a dll, but I can't find anything for vb about how to import an entire class and use it like I show above. I don't know if this is even possible. And realistically, I'm not sure this is even what I want to do since the purpose of putting the memory intensive code with lots of dynamic memory allocation and such in the dll is to keep vb from having to handle it. Conceptually, it seams like importing the entire class would essentially copy all that functionality and memory handling into vb. ...So on to part 2.

Question part 2
I came to the conclusion that importing an entire class and using it as specified above must not be possible (and/or probably not the best way to do it), so I started playing around with other options.

In this option rather than importing the entire class into vb, I was thinking the class (all the functions/variables/memory/etc) would stay on the c++/dll side and I would just call the functions (passing in data or retrieving data) from vb. This is the option I'm currently working with, and where I'm having trouble.

As I said before I've created a much simpler class and compiled it as a dll. There are two functions:
Code:
__declspec(dllexport) void setTestVar(int x) {h_testVar=x;}
__declspec(dllexport) int getTestVar() {return h_testVar;}
The setTestVar function simply sets the value of a member variable, and getTestVar returns the value of that variable.

I load the setTestVar function from the dll like this:
Code:
<DllImport("testLibrary.dll", EntryPoint:="setTestVar", CallingConvention:=CallingConvention.Cdecl)> _
    Public Shared Sub setTestVar(ByVal x As Integer)
    End Sub
Then when I click a button, I call:
Code:
setTestVar(9)
This results in an "AccessViolationException was unhandled" error. "Attempted to read or write protected memory...."
After thinking about it, I guess this would make sense if the constructor in the dll was never called (and thus the variable into which I'm trying to store data doesn't exist).
So the question becomes, how do I call the constructor in the dll from vb such that I have some sort of handle or reference to that object when the call returns from the dll? Without a handle, I won't be able to access any of the member variables. Is this thinking close to being correct? Or is the problem something entirely different?

So again, how do I call the constructor in the dll (from vb) and somehow have access (from vb) to the object that it creates?

Any help would be greatly appreciated!
Thanks.
Reply With Quote
  #2  
Old 12-11-2011, 07:59 PM
snarfblam's Avatar
snarfblamImporting Class from C++ dll snarfblam is offline
Senior Contributor

Forum Leader
* Expert *
 
Join Date: Apr 2005
Location: USA
Posts: 896
Default

If you want to call C++ code from VB, there are two popular options that I can think of. One is for you to make the C++ class a COM component. If you aren't familiar with this topic, it's probably not worth the effort.

The other approach is along the lines of what you are doing, but the info I can share is based on my limited experience with P/Invoke (calling native code).

You can export functions in an unmanaged DLL and call them from VB, but as far as I know, you can only call static functions. A common approach is to use handles. A handle is a value that identifies an object, and would be represented by an IntPtr in VB. VB gets a handle to the object, and then gives that handle to functions to specify which object you want to use or perform an action on. I think the simplest approach is to use a pointer to the object as the handle.

Suppose you want to use the Foo class defined in your C++ code in a VB project. Your DLL should export a function call CreateFoo, which calls the Foo constructor, and returns a pointer to the new Foo object. This pointer will be used as the handle in VB.

The C++ code would look something like this (I'm not a C++ programmer):
Code:
__declspec(dllexport) Foo * CreateFoo(int someParameter) {
    return new Foo(someParameter);
}


VB declaration:

<DllImport("testLibrary.dll", EntryPoint:="CreateFoo", CallingConvention:=CallingConvention.Cdecl)> _
    Public Shared Function CreateFoo(ByVal someParameter As Integer) As IntPtr
    End Sub
Now, suppose Foo has a function called Bar. You could export a function like so:

Code:
// Assuming "int Foo::Bar(int)" is already declared
__declspec(dllexport) int FooBar(Foo *theFoo, int someParameter) {
    if(theFoo) {
        return theFoo->Bar(someParameter);
    } else {
        return 0; // Use false to signal failure
    }
}


VB declaration:

<DllImport("testLibrary.dll", EntryPoint:="CreateFoo", CallingConvention:=CallingConvention.Cdecl)> _
    Public Shared Function FooBar(ByVal theFoo As IntPtr, ByVal someParameter As Integer) As Integer
    End Sub
And to delete the object, you could export a DestroyFoo function. Then, to use a Foo from VB:
Code:
Shared Sub UseAFoo()
    ' Create a Foo
    Dim hFoo As IntPtr = CreateFoo(1024)
  
    ' Call "int Foo::Bar(int)"
    Dim FooBarResult As Integer = FooBar(hFoo, 2048)

    ' Delete Foo
    DestroyFoo(hFoo)

    ' If hFoo were accessible outside this function, we would probably
    ' want to get rid of the dangling pointer
    hFoo = IntPtr.Zero
End Sub
Hope that helps.
__________________
C# _VB.NET _
Reply With Quote
  #3  
Old 12-13-2011, 12:02 PM
-clueless -clueless is offline
Newcomer
 
Join Date: Jul 2009
Posts: 6
Default

Great, thank you so much for the response. Before, I couldn't figure out how to make the pointers work passing them back and forth. This works great!

Thanks!
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Importing Class from C++ dll
Importing Class from C++ dll
Importing Class from C++ dll Importing Class from C++ dll
Importing Class from C++ dll
Importing Class from C++ dll
Importing Class from C++ dll Importing Class from C++ dll Importing Class from C++ dll Importing Class from C++ dll Importing Class from C++ dll Importing Class from C++ dll Importing Class from C++ dll
Importing Class from C++ dll
Importing Class from C++ dll
 
Importing Class from C++ dll
Importing Class from C++ dll
 
-->