How to create an instance of a vb.net class from vc++

  • Thread starter Thread starter S Wheeler
  • Start date Start date
S

S Wheeler

Hi all -

I am trying to create an instance of a vb .net class containing a form from
unmanaged vc++. The vb.net is a dll. How to do this ? I am trying #import by
can't seem to get it quite right. I suspect this is quite simple though.

Thanks in advance...
 
S said:
Hi all -

I am trying to create an instance of a vb .net class containing a
form from unmanaged vc++. The vb.net is a dll. How to do this ? I am
trying #import by can't seem to get it quite right. I suspect this is
quite simple though.

To create a .NET class from unmanaged C++, you either need to compile your
C++ with /clr and use #using to bring the definitions from the .NET assembly
in, or for truly native C++, you need to expose your .NET object via COM.
This can be done by using the COMVisible attribute on your form class and
using regasm (a command line tool from the .NET framework SDK) to register
your .NET assembly as a COM component.

Once your assembly is COM callable, you can use #import from native C++ to
bring in the definitions in the COM type library and use them to instantiate
the VB.NET form from your native C++ code.

-cd
 
Carl -
Thanks for your reply. I have kind of been on this track but was unaware of
COMVisible attribute. I am still having a bit of a problem though; here is
my code:


vb.net project: PTSUI
Imports System.Runtime.InteropServices

<ComVisible(True)> Public Class Form1

Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

Public Sub New()

MyBase.New()

'This call is required by the Windows Form Designer.

InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.

Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

If disposing Then

If Not (components Is Nothing) Then

components.Dispose()

End If

End If

MyBase.Dispose(disposing)

End Sub

'Required by the Windows Form Designer

Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer

'It can be modified using the Windows Form Designer.

'Do not modify it using the code editor.

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

components = New System.ComponentModel.Container

Me.Text = "Form1"

End Sub

#End Region

Public Function SampleFunction() As Integer

Return 10

End Function

End Class


run:
regasm PTSUI.dll /verbose

output:
Types registered successfully

vc++ code
#import "Z:\Development\Experimental\PTS\VBUI\PTSUI\bin\PTSUI.tlb"

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])

{

CoInitialize(NULL);

PTSUI::_Form1Ptr ptr(__uuidof(PTSUI::_Form1));

CoUninitialize();

return 0;

}


Now Intellisense can "see" _Form1Ptr and _Form1 when I type PTSUI::

Here is my compile error:

z:\Development\Experimental\PTS\VC Core\AVPTS\AVPTS\AVPTS.cpp(13): error
C2653: 'PTSUI' : is not a class or namespace name


Thanks for your help!!
 
problem vc++ code

#import "Z:\Development\Experimental\PTS\VBUI\PTSUI\bin\PTSUI.tlb"
#include "stdafx.h"

Compile fails with C2653 is not a class or namespace name

no problem vc++ code:
#include "stdafx.h"
#import "Z:\Development\Experimental\PTS\VBUI\PTSUI\bin\PTSUI.tlb"

Builds sucessfully

Looks like a mistake on my part - stdafx.h contains com header objbase.h so
I guess (?) import needs this ? That seems to make sense.

Thanks for your help!!



S Wheeler said:
Carl -
Thanks for your reply. I have kind of been on this track but was unaware of
COMVisible attribute. I am still having a bit of a problem though; here is
my code:


vb.net project: PTSUI
Imports System.Runtime.InteropServices

<ComVisible(True)> Public Class Form1

Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

Public Sub New()

MyBase.New()

'This call is required by the Windows Form Designer.

InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.

Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

If disposing Then

If Not (components Is Nothing) Then

components.Dispose()

End If

End If

MyBase.Dispose(disposing)

End Sub

'Required by the Windows Form Designer

Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer

'It can be modified using the Windows Form Designer.

'Do not modify it using the code editor.

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

components = New System.ComponentModel.Container

Me.Text = "Form1"

End Sub

#End Region

Public Function SampleFunction() As Integer

Return 10

End Function

End Class


run:
regasm PTSUI.dll /verbose

output:
Types registered successfully

vc++ code
#import "Z:\Development\Experimental\PTS\VBUI\PTSUI\bin\PTSUI.tlb"

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])

{

CoInitialize(NULL);

PTSUI::_Form1Ptr ptr(__uuidof(PTSUI::_Form1));

CoUninitialize();

return 0;

}


Now Intellisense can "see" _Form1Ptr and _Form1 when I type PTSUI::

Here is my compile error:

z:\Development\Experimental\PTS\VC Core\AVPTS\AVPTS\AVPTS.cpp(13): error
C2653: 'PTSUI' : is not a class or namespace name


Thanks for your help!!


Carl Daniel said:
To create a .NET class from unmanaged C++, you either need to compile your
C++ with /clr and use #using to bring the definitions from the .NET assembly
in, or for truly native C++, you need to expose your .NET object via COM.
This can be done by using the COMVisible attribute on your form class and
using regasm (a command line tool from the .NET framework SDK) to register
your .NET assembly as a COM component.

Once your assembly is COM callable, you can use #import from native C++ to
bring in the definitions in the COM type library and use them to instantiate
the VB.NET form from your native C++ code.

-cd
 
S said:
problem vc++ code

#import "Z:\Development\Experimental\PTS\VBUI\PTSUI\bin\PTSUI.tlb"
#include "stdafx.h"

Compile fails with C2653 is not a class or namespace name

no problem vc++ code:
#include "stdafx.h"
#import "Z:\Development\Experimental\PTS\VBUI\PTSUI\bin\PTSUI.tlb"

Builds sucessfully

Looks like a mistake on my part - stdafx.h contains com header
objbase.h so I guess (?) import needs this ? That seems to make sense.

Actually the issue is this: If you're building with precompiled headers
turned on (and presumably you are), then everything before the #include
"stdafx.h" is completely ignored by the compiler.

Glad you solved it!

-cd
 
Spoke too soon...

I have gone through several web references and used the regasm utility to
register the dll but when I try to load the dll from a console vc++ app I
get:

0x80040154 Class not registered

Really annoyed and frustrated - have tried MANY combinations and examples
trying to solve this. Is there a soup to nuts example with source, something
that shows exactly where dll's must live - sounds like in the application
folder. I have tried this from vc and vb both show public class member via
intellisense and compile fine but on run crash. Is this an early / late
binding issue ? Any help is MUCH appriciated.

Thanks
 
S said:
Spoke too soon...

I have gone through several web references and used the regasm
utility to register the dll but when I try to load the dll from a
console vc++ app I get:

0x80040154 Class not registered

Really annoyed and frustrated - have tried MANY combinations and
examples trying to solve this. Is there a soup to nuts example with
source, something that shows exactly where dll's must live - sounds
like in the application folder. I have tried this from vc and vb both
show public class member via intellisense and compile fine but on run
crash. Is this an early / late binding issue ? Any help is MUCH
appriciated.

If your assembly in the GAC? I've had better luck when the COM assembly was
strong-named and in the GAC.

-cd
 
No -
I was trying to avoid mucking up my GAC since this is really just a "proof
of concept" project. I want to get the concepts under control and then as I
feel more proficient with the technical details move it into GAC as kind of
the last hurtle. Are you suggesting that not using GAC has "issues?"

-sw
 
Thanks -
I did not know that...


Carl Daniel said:
Actually the issue is this: If you're building with precompiled headers
turned on (and presumably you are), then everything before the #include
"stdafx.h" is completely ignored by the compiler.

Glad you solved it!

-cd
 
S said:
No -
I was trying to avoid mucking up my GAC since this is really just a
"proof of concept" project. I want to get the concepts under control
and then as I feel more proficient with the technical details move it
into GAC as kind of the last hurtle. Are you suggesting that not
using GAC has "issues?"

Not specifically - I just recall that when I did something similar a couple
years ago, I had better luck with the .NET assembly in the GAC.

-cd
 
Back
Top