C++ class to VB

Joined
Feb 26, 2012
Messages
11
Location
Visalia, California, United States
Programming Experience
10+
I've been trying to pass class pointers back and forth between a VC++ DLL and a VB application.
In my C++ project, I have the following:

MyClass.h:
VB.NET:
#include <Windows.h>

#pragma once


#ifdef MYDLL_EXPORTS
    #define MYDLL_API __declspec(dllexport)
#else
    #pragma message("Automatic link to MYDLL.LIB")
    #pragma comment(lib, "MyDll.lib")
    #define MYDLL_API __declspec(dllimport)
#endif


void* __stdcall CreateClass(int w, int h);
void __stdcall DestroyClass(void *c);
int __stdcall GetWidth(void *c);
int __stdcall GetHeight(void *c);


class MYDLL_API MyClass
{
public:
    MyClass();
    int width;
    int height;
};

MyClass.cpp:
VB.NET:
#include "stdafx.h"
#define MYDLL_EXPORTS
#include "MyClass.h"


MyClass::MyClass()
{
    // Just assigning a couple of test values to test if it worked
    this->width = 20;
    this->height = 10;
}

void* __stdcall CreateClass(int w, int h)
{
    MyClass *foo = new MyClass();
    foo->width = w;
    foo->height = h;
    return foo;
}

void __stdcall DestroyClass(void *c)
{
    MyClass *foo = (MyClass *) c;
    if (foo) delete foo;
}

int __stdcall GetWidth(void *c)
{
    MyClass *foo = (MyClass *) c;
    int w = foo->width;
    return w;
}

int __stdcall GetHeight(void *c)
{
    MyClass *foo = (MyClass *) c;
    int h = foo->height;
    return h;
}

And then in VB:
VB.NET:
Imports System.Runtime.InteropServices


Friend Module API_DECLARES
    Private Const DLL_PATH As String = "C:\Path\To\Dll\"
    Private Const DLL_FILE As String = DLL_PATH & "MyClass.dll"

    <DllImport(DLL_FILE)> Public Function CreateClass(ByVal width As Integer, ByVal height As Integer) As IntPtr
    End Function

    <DllImport(DLL_FILE)> Public Sub DestroyClass(ByRef classPtr As IntPtr)
    End Sub

    <DllImport(DLL_FILE)> Public Function GetWidth(ByRef classPtr As IntPtr) As Int32
    End Function

    <DllImport(DLL_FILE)> Public Function GetHeight(ByRef classPtr As IntPtr) As Int32
    End Function
End Module


Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim hFoo As IntPtr
        Dim w As Int32, h As Int32

        Try
            hFoo = CreateClass(10, 10)
            w = GetWidth(hFoo)
            h = GetHeight(hFoo)
            If hFoo Then DestroyClass(hFoo)
        Catch
        End Try
    End Sub

End Class

The CreateClass() function does seem to return a valid address, however passing it into GetWidth() seems to return the same number whereas GetHeight() always seems to return 0.
And if I call DestroyClass(), I get an assertion error stating "_BLOCK_TYPE_IS_VALID(pHead->BlockUse)".
Can anyone tell me what I'm doing wrong here?
 
Figured it out! In my VB code, I was passing the class pointer ByRef instead of ByVal.
So I changed all three params to ByVal, and viola! It works.
My only guess about that assertion error was that I was attempting to free/overwrite memory currently in use (In this case, the actual IntPtr variables declared in VB, since they were passed by reference).
But all is well now.
 
Back
Top