473,386 Members | 1,873 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Problem with Array from C# to COM

Hi,

i have a problem with a Type Library, which is written in C++.
I am developing an application in C#.NET and have to use functions from
this COM-Type Library. When I use these functions in the "old" VB it
works but not in .NET. I think it is a problem with marshalling but I
could not find a solution yet.

First I included the Type Library in VS.NET 2003. Other functions of
the TL work so the reference to the Lib must be correct.

Here the piece of code in C#.NET:

app = new nwApplication();
int[] id = new int[2];
id[0] = 1;
id[1] = 2;

broadcast = app.get_broadcast(id);

app is an Application-Object of the Library. The array id has two
numbers. The get_broadcast method needs this array as parameter and
returns a broadcast-object.

Here is the PROBLEM. I seems that the get_broadcast method does not get
the content of the array correctly.

I tried it in VB like this:

Dim app, broadcast, id
id = Array(1,2)
Set app = CreateObject("NwLib.nwApplication")
Set broadcast = app.get_broadcast(id)

This works correctly.

When I look for the get_broadcast message in the object browser the
definition is like this:
nwApplication.get_broadcast(object)

When i compile my project, VS.NET creates a Interop.nw.dll. I
disassembled it to IL and looked for the definitions of the method. It
was like this:

......... get_broadcast(object marshal( struct) Value)....

Is it possible that the array in C# is not correctly marshalled?

Has anyone an idea where the problem could be? Thanks very much!

Peter

Jan 23 '06 #1
9 4081
It sounds likely that the array is not being correctly marshalled. For the
C# code you are using, you may have to modify your interop assembly usiing
ildasm, a text editor, and ilasm to compile back. The marshalling in the IL
may have to be changed to something like

marshal(int32[])

or even

marshal(safearray int32)

However I don't know what the method definition looks like in your TLB. The
marshalling specified in the interop dll may well be correct but what you
are trying to do in your C# is incorrect. (I don't know what the VB Array
operation does.)

"mupe" <p.*******@eisenmann.de> wrote in message
news:11*********************@f14g2000cwb.googlegro ups.com...
Hi,

i have a problem with a Type Library, which is written in C++.
I am developing an application in C#.NET and have to use functions from
this COM-Type Library. When I use these functions in the "old" VB it
works but not in .NET. I think it is a problem with marshalling but I
could not find a solution yet.

First I included the Type Library in VS.NET 2003. Other functions of
the TL work so the reference to the Lib must be correct.

Here the piece of code in C#.NET:

app = new nwApplication();
int[] id = new int[2];
id[0] = 1;
id[1] = 2;

broadcast = app.get_broadcast(id);

app is an Application-Object of the Library. The array id has two
numbers. The get_broadcast method needs this array as parameter and
returns a broadcast-object.

Here is the PROBLEM. I seems that the get_broadcast method does not get
the content of the array correctly.

I tried it in VB like this:

Dim app, broadcast, id
id = Array(1,2)
Set app = CreateObject("NwLib.nwApplication")
Set broadcast = app.get_broadcast(id)

This works correctly.

When I look for the get_broadcast message in the object browser the
definition is like this:
nwApplication.get_broadcast(object)

When i compile my project, VS.NET creates a Interop.nw.dll. I
disassembled it to IL and looked for the definitions of the method. It
was like this:

......... get_broadcast(object marshal( struct) Value)....

Is it possible that the array in C# is not correctly marshalled?

Has anyone an idea where the problem could be? Thanks very much!

Peter

Jan 23 '06 #2
....I'm also slightly surprised that the IL doesn't mark the parameter with
[in] (unless you missed that out).

Can you supply the method signature in the type library and the full method
definition in IL?

"mupe" <p.*******@eisenmann.de> wrote in message
news:11*********************@f14g2000cwb.googlegro ups.com...
Hi,

i have a problem with a Type Library, which is written in C++.
I am developing an application in C#.NET and have to use functions from
this COM-Type Library. When I use these functions in the "old" VB it
works but not in .NET. I think it is a problem with marshalling but I
could not find a solution yet.

First I included the Type Library in VS.NET 2003. Other functions of
the TL work so the reference to the Lib must be correct.

Here the piece of code in C#.NET:

app = new nwApplication();
int[] id = new int[2];
id[0] = 1;
id[1] = 2;

broadcast = app.get_broadcast(id);

app is an Application-Object of the Library. The array id has two
numbers. The get_broadcast method needs this array as parameter and
returns a broadcast-object.

Here is the PROBLEM. I seems that the get_broadcast method does not get
the content of the array correctly.

I tried it in VB like this:

Dim app, broadcast, id
id = Array(1,2)
Set app = CreateObject("NwLib.nwApplication")
Set broadcast = app.get_broadcast(id)

This works correctly.

When I look for the get_broadcast message in the object browser the
definition is like this:
nwApplication.get_broadcast(object)

When i compile my project, VS.NET creates a Interop.nw.dll. I
disassembled it to IL and looked for the definitions of the method. It
was like this:

......... get_broadcast(object marshal( struct) Value)....

Is it possible that the array in C# is not correctly marshalled?

Has anyone an idea where the problem could be? Thanks very much!

Peter

Jan 23 '06 #3
Hi,

yes i will post the code tomorrow when I am back in office.

I already disassembled the assembly to IL and then I tried to recompile
it but that did not work.
So I disassembled it and recompiled it without any changes but then I
got an error message
that an entry point was not found and the dll was not created. I will
post the exact error message tomorrow.

Thanks so long.

Jan 23 '06 #4
I don’t know what is the problem but as far as you received the
[nwApplication.get_broadcast(object)]
Object that means you receive the address of the array object and you just
need to work out the indexes/values of your object?

If I missed your point ignore the message.

Vlad P

"mupe" wrote:
Hi,

i have a problem with a Type Library, which is written in C++.
I am developing an application in C#.NET and have to use functions from
this COM-Type Library. When I use these functions in the "old" VB it
works but not in .NET. I think it is a problem with marshalling but I
could not find a solution yet.

First I included the Type Library in VS.NET 2003. Other functions of
the TL work so the reference to the Lib must be correct.

Here the piece of code in C#.NET:

app = new nwApplication();
int[] id = new int[2];
id[0] = 1;
id[1] = 2;

broadcast = app.get_broadcast(id);

app is an Application-Object of the Library. The array id has two
numbers. The get_broadcast method needs this array as parameter and
returns a broadcast-object.

Here is the PROBLEM. I seems that the get_broadcast method does not get
the content of the array correctly.

I tried it in VB like this:

Dim app, broadcast, id
id = Array(1,2)
Set app = CreateObject("NwLib.nwApplication")
Set broadcast = app.get_broadcast(id)

This works correctly.

When I look for the get_broadcast message in the object browser the
definition is like this:
nwApplication.get_broadcast(object)

When i compile my project, VS.NET creates a Interop.nw.dll. I
disassembled it to IL and looked for the definitions of the method. It
was like this:

......... get_broadcast(object marshal( struct) Value)....

Is it possible that the array in C# is not correctly marshalled?

Has anyone an idea where the problem could be? Thanks very much!

Peter

Jan 23 '06 #5
@Vlad P: No, the object I get back from the method needs the value of
the array for internal use. And because of the object´s behaviour I
think that it does not get the value of the array correctly.

@Clive Dixon: Recompilation with ilasm now works. I forgot some options
yesterday. Here I have the pieces of IL code I found in the nw.il after
disassembling it from Interop.Nw.dll. The names of methods could be
different to those I posted yesterday but nwBroadcast is the object I
get back from the method get_nwBroadcast().

.method public hidebysig newslot specialname virtual
instance class nwLib.nwBroadcast
marshal( interface)
get_nwBroadcast(object marshal( struct) Value) runtime
managed internalcall
{
.custom instance void
[mscorlib]System.Runtime.InteropServices.DispIdAttribute::.c tor(int32)
= ( 01 00 0F 00 00 00 00 00 )
.override nwLib.InwApplication::get_nwBroadcast
} // end of method nwApplicationClass::get_nwBroadcast

....

.property class nwLib.nwBroadcast
nwBroadcast(object)
{
.custom instance void
[mscorlib]System.Runtime.InteropServices.DispIdAttribute::.c tor(int32)
= ( 01 00 0F 00 00 00 00 00 )
.get instance class nwLib.nwBroadcast
nwLib.nwApplicationClass::get_nwBroadcast(object)
} // end of property nwApplicationClass::nwBroadcast

....

.method public hidebysig newslot specialname abstract virtual
instance class nwLib.nwBroadcast
marshal( interface)
get_nwBroadcast(object marshal( struct) Value) runtime
managed internalcall
{
.custom instance void
[mscorlib]System.Runtime.InteropServices.DispIdAttribute::.c tor(int32)
= ( 01 00 0F 00 00 00 00 00 )
} // end of method InwApplication::get_nwBroadcast

....

.property class nwLib.nwBroadcast
nwBroadcast(object)
{
.custom instance void
[mscorlib]System.Runtime.InteropServices.DispIdAttribute::.c tor(int32)
= ( 01 00 0F 00 00 00 00 00 )
.get instance class nwLib.nwBroadcast
nwLib.InwApplication::get_nwBroadcast(object)
} // end of property InwApplication::nwBroadcast

Thats all I found to this method.

In another method I get back an object which I cast to System.Array in
my C#-Code. I found in IL code that this is also marshalled as struct.
But that works without any problems?! Here the code:

.method public hidebysig newslot abstract virtual
instance object
marshal( struct)
ScanNet([in] int32 lngStartID,
[in] int32 lngEndID) runtime managed internalcall
{
.custom instance void
[mscorlib]System.Runtime.InteropServices.DispIdAttribute::.c tor(int32)
= ( 01 00 03 00 00 00 00 00 )
} // end of method InwNetwork::ScanNet
I also tried marshal( int32[]) like you told me yesterday but that did
not work. I got an error message: "parameter #1 can not be marshalled.
Invalid managed/unmanaged type combination (the object class has to be
combined with Interface, IUnknown, IDispatch, AsAny or Struct."

I hope you can help me with the code above. Thanks in advance!

Peter

Jan 24 '06 #6
I viewed the Type Lib in the C++ TypeLib Viewer and there it looked
likes this:

[id(0x0000000f), propget, helpstring("property nwBroadcast")]
HRESULT nwBroadcast(
VARIANT Value,
[out, retval] InwBroadcast** pVal);

Since my last entry I tried more things but nothing works....

Jan 24 '06 #7
Seems odd that the System.Array to VARIANT (IL 'struct') marshalling happens
one way but not the other.

Next up, I would suggest you try manually marshalling the array to VARIANT
before you pass it, using Marshal.GetNativeVariantForObject.

You will first need to allocate some memory for the out VARIANT using
Marshal.AllocCoTaskMem. I don't immediately see a way of allocating the
exact size for a VARIANT in C# so you'll probably have to try giving it a
"sufficiently large" amount (from memory a VARIANT is 16 bytes, but don't
quote me on that).

"mupe" <p.*******@eisenmann.de> wrote in message
news:11********************@o13g2000cwo.googlegrou ps.com...
@Vlad P: No, the object I get back from the method needs the value of
the array for internal use. And because of the object´s behaviour I
think that it does not get the value of the array correctly.

@Clive Dixon: Recompilation with ilasm now works. I forgot some options
yesterday. Here I have the pieces of IL code I found in the nw.il after
disassembling it from Interop.Nw.dll. The names of methods could be
different to those I posted yesterday but nwBroadcast is the object I
get back from the method get_nwBroadcast().

.method public hidebysig newslot specialname virtual
instance class nwLib.nwBroadcast
marshal( interface)
get_nwBroadcast(object marshal( struct) Value) runtime
managed internalcall
{
.custom instance void
[mscorlib]System.Runtime.InteropServices.DispIdAttribute::.c tor(int32)
= ( 01 00 0F 00 00 00 00 00 )
.override nwLib.InwApplication::get_nwBroadcast
} // end of method nwApplicationClass::get_nwBroadcast

....

.property class nwLib.nwBroadcast
nwBroadcast(object)
{
.custom instance void
[mscorlib]System.Runtime.InteropServices.DispIdAttribute::.c tor(int32)
= ( 01 00 0F 00 00 00 00 00 )
.get instance class nwLib.nwBroadcast
nwLib.nwApplicationClass::get_nwBroadcast(object)
} // end of property nwApplicationClass::nwBroadcast

....

.method public hidebysig newslot specialname abstract virtual
instance class nwLib.nwBroadcast
marshal( interface)
get_nwBroadcast(object marshal( struct) Value) runtime
managed internalcall
{
.custom instance void
[mscorlib]System.Runtime.InteropServices.DispIdAttribute::.c tor(int32)
= ( 01 00 0F 00 00 00 00 00 )
} // end of method InwApplication::get_nwBroadcast

....

.property class nwLib.nwBroadcast
nwBroadcast(object)
{
.custom instance void
[mscorlib]System.Runtime.InteropServices.DispIdAttribute::.c tor(int32)
= ( 01 00 0F 00 00 00 00 00 )
.get instance class nwLib.nwBroadcast
nwLib.InwApplication::get_nwBroadcast(object)
} // end of property InwApplication::nwBroadcast

Thats all I found to this method.

In another method I get back an object which I cast to System.Array in
my C#-Code. I found in IL code that this is also marshalled as struct.
But that works without any problems?! Here the code:

.method public hidebysig newslot abstract virtual
instance object
marshal( struct)
ScanNet([in] int32 lngStartID,
[in] int32 lngEndID) runtime managed internalcall
{
.custom instance void
[mscorlib]System.Runtime.InteropServices.DispIdAttribute::.c tor(int32)
= ( 01 00 03 00 00 00 00 00 )
} // end of method InwNetwork::ScanNet
I also tried marshal( int32[]) like you told me yesterday but that did
not work. I got an error message: "parameter #1 can not be marshalled.
Invalid managed/unmanaged type combination (the object class has to be
combined with Interface, IUnknown, IDispatch, AsAny or Struct."

I hope you can help me with the code above. Thanks in advance!

Peter
Jan 24 '06 #8
This is the code I tried:

IntPtr mem;

int[] appId = new int[2];
appId[0] = 1;
appId[1] = 2;

mem = Marshal.AllocCoTaskMem(64); // also tried 32.....

Marshal.GetNativeVariantForObject(appId, mem);

nwBroad = nwApp.get_nwBroadcast(mem);

It does not work. It has the same effect like using appId directly as
parameter......

Do I have to edit the IL code for this too??

Thanks.

Jan 24 '06 #9
Today I tried something new. I wrote a VB6-DLL as "debug layer" which
gets the array as parameter. This dll hands the array over to the
getBroadcast method (in VB6 the whole thing works, so I chose VB6). I
returned the array from the dll back to my c# application and I got the
array with the correct numbers in it... but...
....if I hand over the array without doing anything other it does not
work.
If I define a new array in the dll and copy the content of the array I
get as parameter into that new array, it works! So it has something to
do with marshaling. The numbers in the parameter array are correct. If
I view them in debug mode they are of type Variant/Integer.
The new array i define is also Variant/Integer so I do not see any
difference?!?

Jan 27 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: JesusFreak | last post by:
From: us_traveller@yahoo.com (JesusFreak) Newsgroups: microsoft.public.scripting.jscript Subject: toolbar script problem NNTP-Posting-Host: 192.92.126.136 Recently, I downloaded the following...
0
by: crawlerxp | last post by:
This is the problem: I do not get the output I need when encoding and decoding data using rijndael alghoritm. Look at the code and see what the problem is actually: Please paste this code into...
8
by: Brady | last post by:
Hi, I'm having a problem reading and writing to a file. What I'm trying to do is read a file, modify the portion of the file that I just read, and then write the modified data back to the same...
8
by: mytfein | last post by:
Hi Everyone, Background: Another department intends to ftp a .txt file from the mainframe, for me to process. The objective is to write a vb script that would be scheduled to run daily to...
8
by: intrepid_dw | last post by:
Hello, all. I've created a C# dll that contains, among other things, two functions dealing with byte arrays. The first is a function that returns a byte array, and the other is intended to...
4
by: daroman | last post by:
Hi Guys, i've problem with my small C++ programm. I've just small template class which represetns a array, everything works fine up to combination with std::string. I did tried it with M$ VC++ and...
5
by: weidongtom | last post by:
Hi, I tried to implement the Universal Machine as described in http://www.boundvariable.org/task.shtml, and I managed to get one implemented (After looking at what other's have done.) But when I...
9
by: weidongtom | last post by:
Hi, I've written the code that follows, and I use the function add_word(), it seems to work fine *before* increase_arrays() is called that uses realloc() to allocate more memory to words. But...
3
by: raylopez99 | last post by:
Below is my problem. I've narrowed it down to one thing: my unfamiliarity on how class instances are instantiated in an array. This is because the "un-array" / "non-array" version of the program...
25
by: biplab | last post by:
Hi all, I am using TC 3.0..there if I declare a integer array with dimension 162*219...an error msg saying that too long array is shown....what should I do to recover from this problem???
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.