tags:

views:

653

answers:

5

All the examples I can find using DLLImport to call C++ code from C# passes ints back and forth. I can get those examples working just fine. The method I need call takes two structs as its import parameters, and I'm not exactly clear how I can make this work.

Here's what I've got to work with:

I own the C++ code, so I can make any changes/additions to it that I need to.

A third party application is going to load my DLL on startup and expects the DLLExport to be defined a certain way, so i can't really change the method signature thats getting exported.

The C# app I'm building is going to be used as a wrapper so i can integrate this C++ piece into some of our other applications, which are all written in C#.

The C++ method signature I need to call looks like this

DllExport int Calculate (const MathInputStuctType *input, 
    MathOutputStructType *output, void **formulaStorage)

And MathInputStructType is defined as the following

typedef struct MathInputStuctTypeS {
    int    _setData;
    double    _data[(int) FieldSize];
    int    _setTdData;
} MathInputStuctType;
+3  A: 

From the declaration you posted, your C# code will look something like this:

[DllImport("mydll.dll")]
static extern int (ref MathInputStructType input,
    ref MathOutputStructType output, ref IntPtr formulaStorage);

Depending on the structure of MathInputStructType and MathOutputStructType in C++, you are going to have to attribute those structure declarations as well so that they marshal correctly.

casperOne
Missing the function name btw :)
leppie
"you are going to have to attribute those structure declarations as well so that they marshal correctly."Right, this is the part that I don't really understand. I added the struct to my question.
Jonathan Beerhalter
A: 

put the struct in a simple header file.

call swig on your header file

swig -c++ -csharp myheader.h

look at the output

iterationx
I have nothing named swig on my machine, and I have no idea what swig is. Is this something that I can download from someplace?
Jonathan Beerhalter
You can find it at http://www.swig.org/.
LanceSc
+3  A: 

For the struct:

struct MathInputStuctType 
{
    int       _setData;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = FieldSize)]
    double[]  _data;
    int       _setTdData;
}
leppie
I'm not sure if it's 100% necessary but you should set the ArraySubType to UnmanagedType.R8 for the _data field.
JaredPar
That should be inferred (I assume, as the marshaller is pretty good).
leppie
+2  A: 

You might want to look at this project on CodePlex, http://www.codeplex.com/clrinterop/Release/ProjectReleases.aspx?ReleaseId=14120. It should help you marshal the structures correctly.

LanceSc
This looks cool and all, but no matter what DLL I choose, it keeps telling me that expects a manifest. Looks like a cool tool if it worked though.
Jonathan Beerhalter
Didn't know it was that restrictive, sorry about that.
LanceSc
No worries, thanks for the help.
Jonathan Beerhalter
Instead of trying to open a DLL, you can use the SigImp Translate Snippet tab to see how a certain C++ code should be defined in C#.
splintor
+2  A: 

The MSDN topic Passing Structures has a good introduction to passing structures to unmanaged code. You'll also want to look at Marshaling Data with Platform Invoke, and Marshaling Arrays of Types.

Jim Mischel
Thanks so much. This gave me enough of an understanding to get the code working.
Jonathan Beerhalter