1

I have a dll written in C that gets imported into a C# application. All I need from the dll is read out a few values from a hardware device, the actual read process is done by a function in the C dll. Now I want to read out all the values with this single function and return them to C# in an fast and easy way. It is a very "general" multi plattform C library that consists of a few functions to handle the communication with said hardware device. I'm looking for a general "C to C#" answer that doesn't have to be specific for my case.

I'm not very experienced in C and C# which makes the task rather complicated (I have no choice about the language). What would be a smart way to do this in C and how do I declare it in C and how I do import it properly in C#?

Here some Pseudo code to make my question a bit clearer. Thats not valid code but should make clear what I'm after C:

int [] read(){

int results [3];

results[0] = getPosition();
results[1] = getOrientation();
results[2] = getTouch();

return results;
}

C#

[DllImport("myDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int[] read();

int [] cReturn = new int[3];
cReturn = read();

I tried returning an int array and marshal it in C#, as all my values are int types but it seems returning arrays isn't something you would do in C.

I found quite a few examples for C++ but none of them worked with C as they used C++ specific functions.

timonsku
  • 1,249
  • 2
  • 21
  • 45
  • Your question is too general. I think you're going to need to post some code. The signature of the method in your C DLL would be a good start. – Mick Feb 25 '14 at 00:11
  • Declare a struct and pass it by reference. Like int Foo(struct info* retval) – Hans Passant Feb 25 '14 at 00:11
  • Currently no access to my code. I will try to add it in later. Though I would like a general answer as I faced this issue a lot and always came back to using a single function for every variable which is kind of silly. – timonsku Feb 25 '14 at 00:12
  • 1
    A "C dll" can host different kinds of code, and it's important to know what type you've got before you try to call into it from C#. The DLL could be a COM (component object model) DLL, or it could be a simple library of compiled functions. See this article to help you identify what you're working with - http://stackoverflow.com/questions/1420726/how-can-i-detect-the-type-of-a-dll-com-net-win32 – STLDev Feb 25 '14 at 00:13
  • It is the former. I will add that info. – timonsku Feb 25 '14 at 00:14
  • *The latter, sorry. Really just a bunch of pure C functions to call without the need of any plattform specific APIs. – timonsku Feb 25 '14 at 00:23

1 Answers1

4

You can have your C API set the values into pointers passed as arguments, ie:

void your_c_function(int* value1, int* value2)
{
    *value1 = 42;
    *value2 = 43;
}

You can then PInvoke this by ref:

[DllImport("your_dll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int your_c_function(ref int value1, ref int value2);

Note that you can also define a struct in C, and pass the entire struct by pointer, if there are many values to set. This will require recreating the struct definition on the managed side, however.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Thanks, I wasn't aware that this is possible. How do I access the values of the pointers after calling the function though if the C function is a void? I'm not exactly familiar with this concept. – timonsku Feb 25 '14 at 00:20
  • 1
    Nevermind, the MSDN article about "ref" explains it very well. http://msdn.microsoft.com/en-us/library/14akc2c7.aspx Thanks for your simple answer. – timonsku Feb 25 '14 at 00:37