2

I have a function written in c++ that I put in a dll and use in c# using DllImport. Everything works; I am able to get the return value from c++ and display it in my c# GUI. Now I want to add to that function and have it return multiple values (3 so far). I've tried the methods given in Return C++ array to C# and How to return two different variable in c++? but neither work. The code from the first post gives me an access violation error and the code form the second one gives me all 0 values for the struct. For the first one, I even copied the given code exactly and tried to run it but to no avail. What could be causing the errors and wrong values given by these methods? How can I get them to work?

Just in case it is needed, my own code with the implementation of the second post is below.

bisection.h

 struct Result
{
    double root;
    double relError;
    double absError;
}result;
extern "C" {__declspec(dllexport) Result bisection( double l, double u, double stoppingError, int maxIter); }

bisection.cpp

Result bisection(double l, double u, double stoppingError, int maxIter) {
//code for this function
result.root = xr;
result.relError = e;
result.absError = 1;    
return result;
}

c# code

    [StructLayout(LayoutKind.Sequential)]
    public struct Result
    {
        public double root;
        public double relError;
        public double absError;            
    }
    [DllImport(dllPath)]
    private static extern Result bisection(double l, double u, double stoppingError, int maxIter);

Result result = bisection(data[0], data[1], 0.1, 100);
Community
  • 1
  • 1
Aeleon
  • 169
  • 9
  • Your header has `bisection` returning a `double`, while the implementation returns a `Result`. – PaulMcKenzie Aug 04 '16 at 02:30
  • Ah! A mistake from when I was editing my code to post here. I've fixed it. – Aeleon Aug 04 '16 at 02:48
  • Maybe it would be better to pass the Result as an out parameter instead of returning it, and have the C++ code fill the `Result` in that's passed. This would follow in the model of how you call Windows API functions that need to "return a struct" (like `GetMessage`) – PaulMcKenzie Aug 04 '16 at 03:31
  • @PaulMcKenzie Sorry for the late reply, I got sidetracked. This is a great idea. I've implemented it and it's working beautifully; I don't have to mess with arrays and marshalling. I can get the values I need directly.. Plus it frees up the return value with I can now use to determine if the function ran properly. I am expecting situations where it won't; an integer return value denoting the success or failure of a function is a life saver. Thank you! – Aeleon Aug 05 '16 at 02:07

1 Answers1

2

Your code is almost correct. There is a mismatch of calling convention. The C++ code uses cdecl, the C# stdcall. Change one so that they match.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Yep, that was it; this is what did it. I copy pasted the code from a few online sources and i must have messed it up while I was editing to fit my needs. I read up on the calling convention and the default it stdcall; once I changed that, as per your instructions, the code worked. Thanks – Aeleon Aug 05 '16 at 02:08