473,382 Members | 1,355 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,382 software developers and data experts.

Another C# marshaling question

Hi again,

I created a thread some days ago, while I was trying to access a C++ DLL
using my C# program. First of all, I want to thanks all the guys who helped
me. But I still have a problem... My C++ DLL has a function which has the
following prototype:

long FF_Function(void* inInstance, char* inDate, FF_Struct**
outStructure, long* outNumber);

The structure has the following prototype:

struct FF_Struct
{
long m_Index;
char m_ID[FF_ID_LEN];
char m_Date[FF_DATETIME_LEN];
};
I know that the function should return me an array of FF_Struct, and
that the parameter outNumber has the number of elements stored in the
FF_Struct array. Now, I'm tring to translate it in C#, and here is what I
did (which does not work, of course):
public class FF_AO_OrderList
{
public int index;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FF_ID_LEN)]
public string numeroCommande;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FF_DATETIME_LEN)]
public string dateCommande;
}
[DllImport("FF_myDLL.dll")]
public static extern int FF_Function
(
IntPtr inInstance,
[MarshalAs(UnmanagedType.LPTStr)]
string date,
out FF_Struct[] outStructure,
out int outNumber
);
I can access the function, but it returns me an error message ("The
parameters specified for the interface are incorrect."). I don't know how to
deal with this structure and its double pointer. Even in unsafe mode (then I
use a FF_Struct** parameter), I have the same problem.
Does anyone knows what I'm missing ? I'd greatly appreciate some help,
as I'm completely out of ideas... Thanks !!!!

Laurent
Nov 28 '05 #1
2 1941
Laurent,

You are going to have to manually marshal the structure. Your structure
declaration needs to be changed:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public class FF_Struct
{
public int index;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FF_ID_LEN)]
public string numeroCommande;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FF_DATETIME_LEN)]
public string dateCommande;
}

Declaring as a class will tell the CLR that it can re-arrange the order
of the fields as it wishes, which is not what you want in this case.

You will also have to change your function declaration to:

[DllImport("FF_myDLL.dll")]
public static extern int FF_Function(
IntPtr inInstance,
[MarshalAs(UnmanagedType.LPTStr)]
string date,
ref IntPtr outStructure,
ref int outNumber
);

Then, what you have to do on return is marshal the array, like so:

// Allocate the array.
FF_Struct[] outStructs = new FF_Struct[outNumber];

// Cycle through unmanaged memory, and marshal.
for (int index = 0; index < outNumber; index++)
{
// Get the pointer of the location in memory.
IntPtr elementPointer = new IntPtr(outStructure.ToInt64() + (index *
Marshal.SizeOf(typeof(FF_Struct))));

// Now marshal that value.
outStructs[index] = Marshal.PtrToStructure(elementPointer,
typeof(FF_Struct));
}

The only problem here is that you have to figure out how to release the
memory that was allocated for the structure. The function is allocating it,
but you aren't handling that in this situation.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
"Laurent" <mo********@free.fr> wrote in message
news:u2****************@tk2msftngp13.phx.gbl...
Hi again,

I created a thread some days ago, while I was trying to access a C++
DLL using my C# program. First of all, I want to thanks all the guys who
helped me. But I still have a problem... My C++ DLL has a function which
has the following prototype:

long FF_Function(void* inInstance, char* inDate, FF_Struct**
outStructure, long* outNumber);

The structure has the following prototype:

struct FF_Struct
{
long m_Index;
char m_ID[FF_ID_LEN];
char m_Date[FF_DATETIME_LEN];
};
I know that the function should return me an array of FF_Struct, and
that the parameter outNumber has the number of elements stored in the
FF_Struct array. Now, I'm tring to translate it in C#, and here is what I
did (which does not work, of course):
public class FF_AO_OrderList
{
public int index;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FF_ID_LEN)]
public string numeroCommande;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FF_DATETIME_LEN)]
public string dateCommande;
}
[DllImport("FF_myDLL.dll")]
public static extern int FF_Function
(
IntPtr inInstance,
[MarshalAs(UnmanagedType.LPTStr)]
string date,
out FF_Struct[] outStructure,
out int outNumber
);
I can access the function, but it returns me an error message ("The
parameters specified for the interface are incorrect."). I don't know how
to deal with this structure and its double pointer. Even in unsafe mode
(then I use a FF_Struct** parameter), I have the same problem.
Does anyone knows what I'm missing ? I'd greatly appreciate some help,
as I'm completely out of ideas... Thanks !!!!

Laurent

Nov 28 '05 #2
Hi Nicholas,
Thank you for your answer, it works !!! I can access my function and the
returned value is as expected.

But I still have a little problem... this part of code doesn't work "as
it":

for (int index = 0; index < outNumber; index++)
{
// Get the pointer of the location in memory.
IntPtr elementPointer = new IntPtr(outStructure.ToInt64() + (index *
Marshal.SizeOf(typeof(FF_Struct))));

// Now marshal that value.
outStructs[index] = Marshal.PtrToStructure(elementPointer,
typeof(FF_Struct));
}
In fact, the first line is OK and the others have not been read
correctly. When I debug the code, Marshal.SizeOf(typeof(FF_Struct)) = 32. I
wrote the part of memory I have read into a binary file and examinated it
with Hex Editor. The size of my structure is 29. When I manually put this
value into your code, it works perfectly.

I think something is wrong with my FF_Struct class definition, but I
don't know why. I'm sure the size of the char arrays is OK. Prehaps the
problem comes from the '\0' terminated string ??? Do you have any clue ?

Thanks anyway for your help, you taught me a lot of stuffs today ! :)

Laurent

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> a écrit
dans le message de news: O7**************@tk2msftngp13.phx.gbl...
Laurent,

You are going to have to manually marshal the structure. Your
structure declaration needs to be changed:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public class FF_Struct
{
public int index;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FF_ID_LEN)]
public string numeroCommande;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FF_DATETIME_LEN)]
public string dateCommande;
}

Declaring as a class will tell the CLR that it can re-arrange the order
of the fields as it wishes, which is not what you want in this case.

You will also have to change your function declaration to:

[DllImport("FF_myDLL.dll")]
public static extern int FF_Function(
IntPtr inInstance,
[MarshalAs(UnmanagedType.LPTStr)]
string date,
ref IntPtr outStructure,
ref int outNumber
);

Then, what you have to do on return is marshal the array, like so:

// Allocate the array.
FF_Struct[] outStructs = new FF_Struct[outNumber];

// Cycle through unmanaged memory, and marshal.
for (int index = 0; index < outNumber; index++)
{
// Get the pointer of the location in memory.
IntPtr elementPointer = new IntPtr(outStructure.ToInt64() + (index *
Marshal.SizeOf(typeof(FF_Struct))));

// Now marshal that value.
outStructs[index] = Marshal.PtrToStructure(elementPointer,
typeof(FF_Struct));
}

The only problem here is that you have to figure out how to release the
memory that was allocated for the structure. The function is allocating
it, but you aren't handling that in this situation.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
"Laurent" <mo********@free.fr> wrote in message
news:u2****************@tk2msftngp13.phx.gbl...
Hi again,

I created a thread some days ago, while I was trying to access a C++
DLL using my C# program. First of all, I want to thanks all the guys who
helped me. But I still have a problem... My C++ DLL has a function which
has the following prototype:

long FF_Function(void* inInstance, char* inDate, FF_Struct**
outStructure, long* outNumber);

The structure has the following prototype:

struct FF_Struct
{
long m_Index;
char m_ID[FF_ID_LEN];
char m_Date[FF_DATETIME_LEN];
};
I know that the function should return me an array of FF_Struct, and
that the parameter outNumber has the number of elements stored in the
FF_Struct array. Now, I'm tring to translate it in C#, and here is what I
did (which does not work, of course):
public class FF_AO_OrderList
{
public int index;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FF_ID_LEN)]
public string numeroCommande;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FF_DATETIME_LEN)]
public string dateCommande;
}
[DllImport("FF_myDLL.dll")]
public static extern int FF_Function
(
IntPtr inInstance,
[MarshalAs(UnmanagedType.LPTStr)]
string date,
out FF_Struct[] outStructure,
out int outNumber
);
I can access the function, but it returns me an error message ("The
parameters specified for the interface are incorrect."). I don't know how
to deal with this structure and its double pointer. Even in unsafe mode
(then I use a FF_Struct** parameter), I have the same problem.
Does anyone knows what I'm missing ? I'd greatly appreciate some help,
as I'm completely out of ideas... Thanks !!!!

Laurent


Nov 29 '05 #3

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

Similar topics

1
by: C. N. Sridhar | last post by:
Hi, I'm writing a wrapper to a win32 dll in C#. I need to call a method in DLL which has a Variant type reference parameter. How to marshal variant type from win32 (unmanaged code) to C#...
0
by: Ash | last post by:
Hi, Has anyone ever tried using "COM marshaling" for cross- process communication? In particular, I am interested in cross-process marshaling between Managed Server and Unmanaged Client. ...
3
by: Nikolay Petrov | last post by:
Guys, please help. I am trying to make this work from at least 4 months. I am new to programming and some things are difficult to me, but I really need to make my project work. I can't find...
3
by: Rudy Velthuis | last post by:
Hello, Does anyone know how to create a struct that will marshal to the following C++ struct A, containing an array of the user defined String10 type: struct String10 { char SLen; char S;
0
by: Jeff | last post by:
Hi guys Mattias, thanx for answering my last question Well, I'm struggling with marshaling a struct that has **ptr to an array of arrays of struct. Why? I'm stuck with it 1. I need to know...
2
by: mirek | last post by:
Hi, I'm trying to import my old code to the .NET using managed wrappers. I've read "Managed Extensions for C++ Migration Guide" document and was trying to do what it stated in it. For example if...
1
by: Laurent | last post by:
Hi again, I need your help again for my C# programm calling a C++ DLL. This is driving me crazy... I have a function defined like this: long FF_AO_GetOrderInfo ( void* inInstance, char*...
25
by: MuZZy | last post by:
Hi, I'm currently rewriting some functionality which was using multithredaing for retrieving datasets from database and updating a grid control. I found that the grids (Infragistics UltraGrid,...
1
by: Bill Medland | last post by:
I am trying to do some P/Invoke custom marshaling and am looking for a little help on custom marshaling a value type. I am working based on Kate Gregory's "Arranging Custom Marshaling With...
0
by: jpogorman | last post by:
Hello, I am trying to get c# custom marshaling working in a particular scenario but it does not appear to be working or not jumping into my marshaling class when I try to debug it. I am try to...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
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:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.