Passing array of int to c DLL

A

Albert Albani

Hello

I have a problem that I cannot seem to solve

I have a c funtion in a DLL that basically looks like
func_c (some_struct* s) {...}

some_struct is defined like so:

struct some_struct {
int count_bytes; // number of
// elements in array_int
int* array_int;
}

In the c# code, I go like

[DllImport("my.dll")]
unsafe private static extern int func_c(some_struct** ao);

/*...*/

unsafe private SOME_FUNC_NAME () {
some_struct s = new some_struc;
s.count_bytes = 10;

// here, I want to set
// s.array[0] = 44;
// s.array[1] = 58;
//...
// s.array[9] = 10;
}


But I have no idea how to create the array (new int[] or what)
and how to assign the numbers to the array.

Any help appreciated
Albert
 
W

Willy Denoyette [MVP]

Albert Albani said:
Hello

I have a problem that I cannot seem to solve

I have a c funtion in a DLL that basically looks like
func_c (some_struct* s) {...}

some_struct is defined like so:

struct some_struct {
int count_bytes; // number of
// elements in array_int
int* array_int;
}

In the c# code, I go like

[DllImport("my.dll")]
unsafe private static extern int func_c(some_struct** ao);

/*...*/

unsafe private SOME_FUNC_NAME () {
some_struct s = new some_struc;
s.count_bytes = 10;

// here, I want to set
// s.array[0] = 44;
// s.array[1] = 58;
//...
// s.array[9] = 10;
}


But I have no idea how to create the array (new int[] or what)
and how to assign the numbers to the array.

Any help appreciated
Albert

Ok, here I suppose your function signature and struct declarations are
exactly as you posted.
Basically you are passing a "pointer to a structure, containing an int and a
pointer to an array of int's", right?
What you have to do is create/fill the array, create a GCHandle to pin the
array during the call , set array_int to the address of the first element
of the (pinned) array and pass this struct by ref.

Herewith a working sample illustrating the process:

// CPP file
#include <iostream>
struct some_struct {
int count_bytes; // number of
// elements in array_int
int* array_int;
};

extern "C" {
__declspec(dllexport) int func_c (some_struct* s);
}
int func_c (some_struct* s)
{
for(int j = 0; j < s->count_bytes; j++)
std::cout << *s->array_int++ << std::endl;
return s->count_bytes;
}


//CS file
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
struct S
{
internal int size;
internal IntPtr pIntArray;
}
class Tester
{
[DllImport("native.dll")]
private static extern int func_c(ref S ao);
static void Main()
{
int[] IntArray = new int[10] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
S s = new S();
s.size = 10;
GCHandle gcH = GCHandle.Alloc(IntArray);
s.pIntArray = Marshal.UnsafeAddrOfPinnedArrayElement(IntArray, 0);
Console.WriteLine(func_c(ref s));
gcH.Free();
}
}


Willy.
 
A

Albert Albani

Willy, you're THE HERO

This is exactly what I needed. Thanks a lot and more

Albert


Albert Albani said:
Hello

I have a problem that I cannot seem to solve

I have a c funtion in a DLL that basically looks like
func_c (some_struct* s) {...}

some_struct is defined like so:

struct some_struct {
int count_bytes; // number of
// elements in array_int
int* array_int;
}

In the c# code, I go like

[DllImport("my.dll")]
unsafe private static extern int func_c(some_struct** ao);

/*...*/

unsafe private SOME_FUNC_NAME () {
some_struct s = new some_struc;
s.count_bytes = 10;

// here, I want to set
// s.array[0] = 44;
// s.array[1] = 58;
//...
// s.array[9] = 10;
}


But I have no idea how to create the array (new int[] or what)
and how to assign the numbers to the array.

Any help appreciated
Albert

Ok, here I suppose your function signature and struct declarations are
exactly as you posted.
Basically you are passing a "pointer to a structure, containing an int and a
pointer to an array of int's", right?
What you have to do is create/fill the array, create a GCHandle to pin the
array during the call , set array_int to the address of the first element
of the (pinned) array and pass this struct by ref.

Herewith a working sample illustrating the process:

// CPP file
#include <iostream>
struct some_struct {
int count_bytes; // number of
// elements in array_int
int* array_int;
};

extern "C" {
__declspec(dllexport) int func_c (some_struct* s);
}
int func_c (some_struct* s)
{
for(int j = 0; j < s->count_bytes; j++)
std::cout << *s->array_int++ << std::endl;
return s->count_bytes;
}


//CS file
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
struct S
{
internal int size;
internal IntPtr pIntArray;
}
class Tester
{
[DllImport("native.dll")]
private static extern int func_c(ref S ao);
static void Main()
{
int[] IntArray = new int[10] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
S s = new S();
s.size = 10;
GCHandle gcH = GCHandle.Alloc(IntArray);
s.pIntArray = Marshal.UnsafeAddrOfPinnedArrayElement(IntArray, 0);
Console.WriteLine(func_c(ref s));
gcH.Free();
}
}


Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top