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