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

  • Thread starter Thread starter Guest
  • Start date Start date
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.
 
I do all my vb6 interop through COM , this works great

maybe this is an idea for you to ?

Regards

Michel
 
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
 
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
 
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.
 
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
 
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
 
Ok so you're suggesting I try

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

I'll post the results a little later.

Regards.
 
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
 
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,
 
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.
 
Back
Top