need to call managed code from unmanaged c++ code !

G

Guest

Hi,

I have a requirement where I need to call methods written in VB.Net from a
C++ code. I have been going crazy reading various articles on the net w.r.t
interop and marshalling but an more confused now that before.

the signature I need to conform in the VB.Net DLL is
int MyAppInitFunc(int argc, char** argv)

To this extent I have tried the following
Public Function MyAppInitFunc(ByVal argc as integer, ByRef argv as string)
as Integer
Public Function MyAppInitFunc(ByVal argc as Int32, ByVal argv() as string)
as Int32

.... based on some posts I even tried
Public Function MyAppInitFunc(ByVal argc as Int32, ByVal argv as IntPtr) as
Int32

but have not been able to get anything to work.

Is there perhaps some reading I'm missing up on ?

Regards.
 
M

Michel Posseth [MCP]

I do all my vb6 interop through COM , this works great

maybe this is an idea for you to ?

Regards

Michel
 
M

Mattias Sjögren

the signature I need to conform in the VB.Net DLL is
int MyAppInitFunc(int argc, char** argv)

Does that mean the C++ caller expects such a function to be a staticly
exported entrypoint from the DLL? VB doesn't let you do that.


Mattias
 
G

Guest

Hello Michel,

Please explain.. I have made my project with "Register for COM Interop". I
have also done a regasm /tlb:.....

All my functions are ComVisible().

Since there is a difference in the VB.Net DLL's and classic Win32 DLL's,
I've even done the IL tweaking to ensure that my functions are being exported.

I can't figure out how to get Char** marshalled into my managed code ?

The combinations Ive tried are
1. <MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VarEnum.VT_BSTR)>
ByVal argv as string()

This gives me an error saying SafeArray of rank 11888 has been passed to a
method expecting an array of rank 1

2. <MarshalAs(Unmanaged.LPArray)> ByRef argv as string

This gives me an error saying cannot marshal 'parameter #2' : Invalid
managed/unmanaged type combination (string parameters and return types must
be paired with LPStr, LPWStr, LPTStr, BSTR, TBStr, VBByRefStr, or AnsiBStr).

and combiantions of the above with char()() instead of string() etc, etc.
x--
Ravi Shankar
 
G

Guest

Hi Mattias,

I has to do some IL tweaking to get my functions exported. Now If I can get
definitions that would permit my variables to be marshalled properly to
unmanaged code, it'd work.
 
M

Mattias Sjögren

I has to do some IL tweaking to get my functions exported. Now If I can get
definitions that would permit my variables to be marshalled properly to
unmanaged code, it'd work.

OK, assuming you get that part to work, I recommend that you go with
the third method signature you posted (with ByVal argv as IntPtr). You
also have to make sure the calling convention is correct.


Mattias
 
Joined
Jun 18, 2007
Messages
1
Reaction score
0
inputs from you

Hi Ravi,

I am attempting the same where I wish to have a VB.Net class library functions to be available to C++. However, I am not able to determine how to create the wrapper and reference it in C++. Is there an article you can point me that helps get this done ? OR can you explain it from what you have already done.

I am sorry this is seeking information from you rather than solving your problem.

thanks,
rama

=?Utf-8?B?UmF2aSBTaGFua2Fy?= said:
Hi,

I have a requirement where I need to call methods written in VB.Net from a
C++ code. I have been going crazy reading various articles on the net w.r.t
interop and marshalling but an more confused now that before.

the signature I need to conform in the VB.Net DLL is
int MyAppInitFunc(int argc, char** argv)

To this extent I have tried the following
Public Function MyAppInitFunc(ByVal argc as integer, ByRef argv as string)
as Integer
Public Function MyAppInitFunc(ByVal argc as Int32, ByVal argv() as string)
as Int32

.... based on some posts I even tried
Public Function MyAppInitFunc(ByVal argc as Int32, ByVal argv as IntPtr) as
Int32

but have not been able to get anything to work.

Is there perhaps some reading I'm missing up on ?

Regards.

--
Ravi Shankar
 
G

Guest

Ok so you're suggesting I try

<MarshalAs(Unmanaged.LPArray)> ByVal argv as IntPtr ?

I'll post the results a little later.

Regards.
 
M

Mattias Sjögren

Ok so you're suggesting I try
<MarshalAs(Unmanaged.LPArray)> ByVal argv as IntPtr ?


You can remove the MarshalAs attribute, it has no effect on IntPtrs.


Mattias
 
G

Guest

Hi Mattias,

I tried what you've suggested and the program went into a non-terminable
state with continuous error pop-ups stating

Unhandled Exception at 0x008f213a in ....exe: 0xC0000005: Access violations
reading loactions 0x00000000

Which sound like a "null" pointer exception to me in a different package :)

Regards,
 
G

Guest

Hi,

I managed to resolve the problems I've been facing so I thought I'd post it
here in case someone else runs into them.

1. I was using a class defintion - this is wrong (come to think about it)..
it should have been declared a Module [ as a result, the private members were
inaccessible and hece my "access violations". Decalring it as a module caused
the private members to be declared during the DLL Load and accessible
thence.] :)

2. the signature "int AppInitFn(int argc, char** argv)" should be
implemented as follows : Public Function(ByVal argc as Int32,
<MarshalAs(UnmanagedType.LPArray, ArraySubType:=UnmanagedType.LPStr,
SizeParamIndex:=0)> ByVal argv() as string) as Int32

I was so sure that the "char** argv" passed through traditional C/C++ is a
string array but the "Access Violation" because of 1 kept throwing me off :)

I tried the "Public Function(ByVal argc as Int32, ByVal/byRef argv as
IntPtr) as Int32" but eventhough I got the value of argc as "3", i could only
marshal the first parameter through the Marshal.PtrToANSI call....

So the above defintion tell the Interop to marshal char** argv as a array of
LongPointers (LPArray) with subtype as LPStr (null terminated string) and use
the first parameter "argc" to define the size of this array... Phew.

Hope this helps.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top