By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,369 Members | 1,692 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,369 IT Pros & Developers. It's quick & easy.

How can i pass structure into c function that expect pointer

P: n/a
hi,
i have couple of qeustions:

1. I have built a interop of c dll. In this dll i have a function that
expect a pointer to a struct.
I want to pass a struct from my c# interop into this c function. how
can I change my c# struct into a pointer that i could send to the c
function?

2. how can i send a null to this function that ecpect pointer to
struct?

Appreciate help,
Guy

May 6 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
I had a similar problem: I wanted to access the GNU MP library (infinite
precision arithmetic, http://gmplib.org/, ) via a C# class. To solve the
problem, I used VS C++. This allows you to create a .NET class that can be
accessed by C#, but that can contain pointers to structures.

The header file for GMP is gmp.h and contains the various C++ data types.
This
is the only GMP source you need (a dll for Visual C++ is available, see
below).

I defined a .h header file that included gmp.h and that also defined a "C++"
class, GMP. Some of the code therein looks like:
using namespace System;
using namespace System::Runtime::InteropServices;
#include "gmp.h"

typedef __mpz_struct * mpzPtr_t;
#define OTHER_MPZ(obj) ((mpzPtr_t)(obj->mpzPtr))
#define THIS_MPZ ((mpzPtr_t)(mpzPtr))

namespace gmpX {

public class GMP
{
public:
[DllImport("gmp.dll")]
static void mpz_add(mpz_t addIn, mpz_t add1, mpz_t add2);

[DllImport("gmp.dll")]
static void mpz_addmul_ui(mpz_t addIn, mpz_t mult1, unsigned long int
mult2);
...... and many more functions, corresponding to the C functions in gmp.h.
These do the multiple precision arithmetic.

I then defined a GmpInt class to be accessed via C# as:

public ref class GmpInt: IDisposable
{
private:
unsigned long mpzPtr;
public:
GmpInt();
GmpInt(unsigned int initVal);
GmpInt(int initVal);
~GmpInt();

double asDouble();

String ^ asString();

int asInt();

void add(GmpInt^ add1, GmpInt^ add2);

... and more functions corr. to the functions I needed. This class
represents an integer that can have as many digits as required. Note the
use of GmpInt^ to define the input. This allows C++ to look at the objects
as "pointers" to the corresponding C# object. Note the mpzPtr defined as an
unsigned long. This is a pointer to the C++ structure that GMP passes
around to do the arithmetic.

You define the functions for class GmpInt are defined in a .cpp file thus:
#include <malloc.h>
#include "stdafx.h"

#include "gmpX.h"
using namespace gmpX;

//3 constructors.
GmpInt::GmpInt()
{
mpzPtr_t bitPtr = new __mpz_struct;
mpzPtr = (unsigned long)bitPtr;
GMP::mpz_init(bitPtr);
}

GmpInt::GmpInt(unsigned int iVal)
{
mpzPtr_t bitPtr = new __mpz_struct;
mpzPtr = (unsigned long)bitPtr;
GMP::mpz_init_set_ui(bitPtr, iVal);
}

GmpInt::GmpInt(int iVal)
{
mpzPtr_t bitPtr = new __mpz_struct;
mpzPtr = (unsigned long)bitPtr;
GMP::mpz_init_set_si(bitPtr, iVal);
}

GmpInt::~GmpInt() //remember: this destructor is called upon Dispose
{
GMP::mpz_clear((mpz_ptr)mpzPtr);
delete (mpzPtr_t)mpzPtr;
}
void GmpInt::add(GmpInt^ add1, GmpInt^ add2) //add to big ints.
{
GMP::mpz_add(THIS_MPZ, OTHER_MPZ(add1), OTHER_MPZ(add2));
}

void GmpInt::addMultiply(GmpInt^ mult1, unsigned int mult2)
{
GMP::mpz_addmul_ui(THIS_MPZ, OTHER_MPZ(mult1), mult2);
}

..... and other functions similarly implemented by
calling the C++ function in the dll.

The GMP C dll for VS is available on the net, precompiled and ready to go:
http://www.cs.nyu.edu/exact/core/gmp/
If you do not have VS for C++, you can download a free "Express" version
from MS:
http://msdn.microsoft.com/vstudio/express/visualc/



<gu**********@googlemail.comwrote in message
news:11**********************@y5g2000hsa.googlegro ups.com...
hi,
i have couple of qeustions:

1. I have built a interop of c dll. In this dll i have a function that
expect a pointer to a struct.
I want to pass a struct from my c# interop into this c function. how
can I change my c# struct into a pointer that i could send to the c
function?

2. how can i send a null to this function that ecpect pointer to
struct?

Appreciate help,
Guy

May 6 '07 #2

P: n/a
On 6 May 2007 02:37:03 -0700, gu**********@googlemail.com wrote:
>hi,
i have couple of qeustions:

1. I have built a interop of c dll. In this dll i have a function that
expect a pointer to a struct.
I want to pass a struct from my c# interop into this c function. how
can I change my c# struct into a pointer that i could send to the c
function?
Have you tried unsafe and fixed?

myData thisStuff = new myData();
unsafe {
fixed (myData* ptr = &thisStuff) {
c_library_function(ptr);
}
}
>
2. how can i send a null to this function that ecpect pointer to
struct?
This compiles - you don't need the fixed statement because null is
inherently fixed as it does not live on the managed heap:

unsafe {
int* voidPtr = null;
c_library_function(voidPtr);
}

rossum

>
Appreciate help,
Guy
May 6 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.