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 / October 2005

Tip: Looking for answers? Try searching our database.

C#/C++ interop and struct

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Luca Beretta - 04 Oct 2005 11:39 GMT
i've a C++ dll with a function that return a pointer to a struct, and i need to
call that function from a C# windows app.
i already try some ways founded on the MSDN and on the web but i cannot map
returned struct to a managed struct.

// C++ Code

struct NKAF
{
    char* SectorCode;
    char* CountryCode;
    char* AgencyCode;
    char* TaxNumber;
};

// function prototype
extern "C" __declspec(dllexport) void Netlink_Read_NKAF(NKAF*);

// C# code
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
public struct NKAF
{
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=16)] string SectorCode;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=16)] string CountryCode;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=16)] string AgencyCode;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=16)] string TaxNumber;
}

[DllImport("scgx.dll")]
public static extern void Netlink_Read_NKAF(IntPtr FreeData);

private void frmMain_Load(object sender, System.EventArgs e)
{
    NKAF dati = new NKAF();
    GCHandle hGC = new GCHandle();
    hGC = GCHandle.Alloc(dati,GCHandleType.Pinned);
    Netlink_Read_NKAF(hGC.AddrOfPinnedObject());
}

when i execute i get this exception

"System.ArgumentException" in mscorlib.dll
Additional information: Object contains non-primitive or non-blittable data

i think the problem is the managed string datatype; if i replace them with int
all works fine (but obviusly i get a nullreference exception after the call
to the function)

any idea or suggestion ? are there any other ways to do this ?
Mattias Sjögren - 04 Oct 2005 15:52 GMT
Luca,

>i've a C++ dll with a function that return a pointer to a struct, and i need to
>call that function from a C# windows app.
[...]
>// function prototype
>extern "C" __declspec(dllexport) void Netlink_Read_NKAF(NKAF*);

There's no way the function can return a pointer since the only
parameter is passed by value, and the function has a void return type.

I'll assume that the function simply populates the fields of the
existing struct you pass in.

>// C++ Code
>
[quoted text clipped - 5 lines]
>    char* TaxNumber;
>};
[...]
>// C# code
>[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
[quoted text clipped - 5 lines]
>[MarshalAs(UnmanagedType.ByValTStr,SizeConst=16)] string TaxNumber;
>}

Since the strings in the C++ declaration aren't fixed-size, you should
remove the MarshalAs attirbutes in the C# declaration.

>[DllImport("scgx.dll")]
>public static extern void Netlink_Read_NKAF(IntPtr FreeData);

Not sure why you chose IntPtr as the parameter type. It would be much
easier with

public static extern void Netlink_Read_NKAF(ref NKAF FreeData);

Mattias

Signature

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

Luca Beretta - 04 Oct 2005 16:40 GMT
Mattias,
first thanks you a lot for your answer; then, my function in C++ dll do
following things:

extern "C" __declspec(dllexport) void Netlink_Read_NKAF(NKAF *FreeData)
{
    NKAF ret;
    /* initialize structure */
    ret.Address = '\0';
    ret.AgencyCode = '\0';
    ret.BirthDate = '\0';

               // populate all the fields reading a smartcard (sample)
               ret.DoctorCode = new char[dwSubSub84L];
    for(DWORD idx = 0; idx < dwSubSub84L; idx++)
               {
    ret.DoctorCode[idx] = (BYTE)NKAF_Stream_Data[jdx+idx+1];
    }
    ret.DoctorCode[idx] = '\0';

               FreeData = &ret;
}

in my original dll i've a different function prototype, that receive no
parameters and return directly the pointer, but i've some problem in the
interop with C#, so reading MSDN i founded some samples like mine actual
version.

i need to change my c++ code ? which is the best way ?

now i changed my C# code to use ref like this:

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
public struct NKAF
{
    string SectorCode;
    string CountryCode;
    string AgencyCode;
}

[DllImport("scgx.dll")]
public static extern void Netlink_Read_NKAF(ref NKAF FreeData);

NKAF dati = new NKAF();
Netlink_Read_NKAF(ref dati);

but i get a System.NullReferenceException

> Luca,
>
[quoted text clipped - 42 lines]
>
> Mattias
Mattias Sjögren - 07 Oct 2005 23:11 GMT
Luca,

>extern "C" __declspec(dllexport) void Netlink_Read_NKAF(NKAF *FreeData)
[...]
>                FreeData = &ret;
>}

This wont work. You're only changing the local pointer value of the
argument, not what it points to. So no changes will propagate back to
the caller.

Instead of populating a new NKAF struct(ret) in the function code, you
could modify the existing one:

FreeData->Address = '\0';

and so on. But you may have to change the C# declarations to use
IntPtr instead of string if you chose to do it this way.

Also if you return pointers to buffers allocated with new, like in

ret.DoctorCode = new char[dwSubSub84L];

you have to provide a way for the caller to free that memory.

Mattias

Signature

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


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.