Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / September 2005

Tip: Looking for answers? Try searching our database.

Marshaling a pointer type

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Tahir Sultan - 14 Sep 2005 13:49 GMT
I am developing an application in C# using Microsoft visual studio .NET 2003.
Basically, I imported a com dll in my application by adding reference to the
COM dll.  The com event in the original dll has the following signature:

HSESULT AddModifyGroupIndication(
[in] unsigned long groupListSize,
[in, size_is(groupListSize)] groupListStruct* groupList)

where groupListSize is number of items (structures) the groupList pointer is
pointing to and
groupList is a pointer to first item (structure of type groupListStruct) in
the memory.

when I imported the dll, the .NET interop marshaller converted the above
event as follows:

.method public hidebysig newslot abstract virtual
           instance void  AddModifyGroupIndication(
[in] valuetype unsigned int32 groupListSize,
[in] valuetype TCSAPILib.groupListStruct& groupList) runtime managed
internalcall

As shown above the pointer (groupList) to first structure in the memory got
converted to a reference (ref) to the structure.

I am doing the following in AddModifyGroupIndication event handler in C# to
get all the items (structures) but it does not work:

------------------
private void RadioSubscriberManagerClass_AddModifyGroupIndication(
uint groupListSize,
ref TCSAPILib.groupListStruct groupList)
{

IntPtr fp;
IntPtr np;
TCSAPILib.groupListStruct  obj ;           
           
unsafe
{                               
int size = System.Runtime.InteropServices.Marshal.SizeOf(typeof
(TCSAPILib.groupListStruct  ));

fp = new IntPtr(size*(groupListSize));                               
try
{                   
  fp = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(size* (int)  
groupListSize);                       
 
System.Runtime.InteropServices.Marshal.StructureToPtr groupList,fp,true);
                                                                               
for ( int i = 0; i < groupListSize; i ++ )
{                       
   np = new IntPtr((int)fp + (i * size));                                  
         
 
obj  = (TCSAPILib.groupListStruct )  
System.Runtime.InteropServices.Marshal.PtrToStructure( np,
typeof(TCSAPILib.groupListStruct ));

OnDebugEvt("---"+obj.groupAddress.ssi.ToString()); //debug
}
}
catch (Exception e1)
{
 OnDebugEvt("---Exception: "+e1.ToString());
}
finally
{
   System.Runtime.InteropServices.Marshal.FreeCoTaskMem(fp);   
}

}       

-------------------------------

The problem----
1.  The problem is StructureToPtr method seems to be coping only first
structure from the memory.
2.  As we cannot not get memory address of a managed type (groupList), how
would I get the remaining items (structures) in the memory in my event
handler.

Mattias Sjögren - 14 Sep 2005 16:44 GMT
>when I imported the dll, the .NET interop marshaller converted the above
>event as follows:
[quoted text clipped - 4 lines]
>[in] valuetype TCSAPILib.groupListStruct& groupList) runtime managed
>internalcall

I suggest you change the parameter type to an array, as described in
the section "Conformant C-Style Arrays" at

http://msdn.microsoft.com/library/en-us/cpguide/html/cpconeditinginteropassembly.asp

Mattias

Signature

Mattias Sjögren [MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Tahir Sultan - 15 Sep 2005 10:00 GMT
Mattias,

I have already tried this solution but it did not work.  What happened was I
did not get the event at all. I mean the the AddModifyGroupIndication event
never got fired.  It could be that the actual groupList type is a pointer as
defined on the actual interface and we are not allowed to marshal it to an
array type.  Please suggest any other solution.----Thanks.

> >when I imported the dll, the .NET interop marshaller converted the above
> >event as follows:
[quoted text clipped - 11 lines]
>
> Mattias
Mattias Sjögren - 16 Sep 2005 22:34 GMT
Tahir,

>I have already tried this solution but it did not work.  What happened was I
>did not get the event at all. I mean the the AddModifyGroupIndication event
>never got fired.  It could be that the actual groupList type is a pointer as
>defined on the actual interface and we are not allowed to marshal it to an
>array type.  Please suggest any other solution.----Thanks.

Well the only other option I can think of is to change the parameter
type to an IntPtr and do the copying yourself.

But using an array should work if done right.

Mattias

Signature

Mattias Sjögren [MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Tahir Sultan - 20 Sep 2005 14:58 GMT
Mattias,

I have tried many times but I am not getting AddModifyGroupIndication  
event.  I did the following changes to Interop.TCSAPILib.il file:

1.  .method public hidebysig newslot abstract virtual
         instance void  AddModifyGroupIndication(
             [in] unsigned int32 groupListSize,
             [in] valuetype TCSAPILib.groupListStruct& groupList) runtime
managed internalcall

--> Replaced with
 .method public hidebysig newslot abstract virtual
         instance void  AddModifyGroupIndication(
             [in] unsigned int32 groupListSize,
             [in] valuetype TCSAPILib.groupListStruct[]  marshal([])
groupList) runtime  managed internalcall

2.  .method public virtual instance void
           Invoke(
              [in] unsigned int32 groupListSize,
              [in] valuetype TCSAPILib.groupListStruct& groupList) runtime
managed

---> Replaced with
 .method public virtual instance void
           Invoke(
              [in] unsigned int32 groupListSize,
              [in] valuetype TCSAPILib.groupListStruct[] marshal([])
groupList) runtime managed

3.  .method public virtual instance void
           AddModifyGroupIndication(
                   unsigned int32 A_1,
                   valuetype TCSAPILib.groupListStruct& groupList A_2) cil
managed
 
---> Replaced with
.method public virtual instance void
           AddModifyGroupIndication(
                   unsigned int32 A_1,
                   valuetype TCSAPILib.groupListStruct[] marshal([])
groupList A_2) cil managed

Then, I generated a new dll from this modified Interop.TCSAPILib.il files,
removed refernce to old dll and added a reference to this newly generated
dll. When, I hooked up this AddModifyGroupIndication event with modifed
parameter, I got the event signature with the following parameters in my C#
code:

 uint groupListSize,
 TCSAPILib.groupListStruct[]   groupList

This event is getting fired by the Com Server but I do not get it.  Could
you please identify if I am missing something OR I am doing wrong
modification to the Interop.TCSAPILib.il file.----Thanks.



> Tahir,
>
[quoted text clipped - 10 lines]
>
> Mattias
Tahir Sultan - 21 Sep 2005 16:41 GMT
Mattias,

It works.  Thanks.  Basically, I tried with IntPtr and it worked.  Now, I
think IntPtr points to unmanaged heap and Com server is responsible to free
the memory. Is that right?

Thanks.

> Mattias,
>
[quoted text clipped - 69 lines]
> >
> > Mattias
Mattias Sjögren - 22 Sep 2005 22:18 GMT
>Now, I
>think IntPtr points to unmanaged heap and Com server is responsible to free
>the memory. Is that right?

Yes, since it's an in parameter the caller frees it.

Mattias

Signature

Mattias Sjögren [MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Tahir Sultan - 23 Sep 2005 09:24 GMT
Thanks, Mattias.

> >Now, I
> >think IntPtr points to unmanaged heap and Com server is responsible to free
[quoted text clipped - 3 lines]
>
> Mattias

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.