0

I have no further ideas how to debug this bug, so asking for advice.

Essentially, I have a C++ DLL, which has a boolean function

class Point
{
   Public: 
   double x;
   double y;

   // lots of operators
}

typedef struct SomeStructParent
{
    bool isValid;

    int64_t StartTime;
    int64_t EndTime;
} SomeStructParent;

typedef struct SomeStruct : SomeStructParent
{
    Point Center;
} SomeStruct;

bool func(SomeStruct & arg)
   { return some_var; }

some_var is initiated to false. The only place in the code where it is set to true has a logger printing. The return value of func is also printed to logger regularly.

C# imports the function like so:

public struct EtPoint
    {
        public double x;
        public double y;
    }

[StructLayout(LayoutKind.Sequential)]
public struct SomeStruct 
    {
        bool isValid;

        // in milliseconds using tracker epoch
        public long StartTime;
        long EndTime;

        public EtPoint Center;       
    }

[DllImport("ETHAL.dll", EntryPoint = "func", CallingConvention = CallingConvention.Cdecl)]
public static extern bool func(ref SomeStruct data);

Under some conditions, calling func from C# returns true, even though the logger shows it as false - the regular prints are false and the line that shows it was set does not occur. With a modified function bool funcArg(SomeStruct & arg, bool & ret) { ret = some_var; }, ret is reliably false under the same conditions.

Perhaps the most annoying/perplexing part: when adding a debug print inside func, it returns the correct value. The same happens when I add Sleep(500). This makes me suspect some kind of multithreading shenanigans, but as I said - only one place in the code where the some_var is assigned true, and it isn't reached in this run.

Is there something with the interaction of C# and C++ that could account for this?

6
  • it would be good if you put the C# code in there ;) Commented Sep 1, 2016 at 7:29
  • 1
    Incorrect function signature causing UB? Multithreading? Some other part of the program writing in memory it shopuldn't write? Hard to tell without more info.. Commented Sep 1, 2016 at 7:29
  • I've added the C# calling. The rest of it... well, I don't expect SO to find multithreading bugs in my code, I was specifically asking about C# and C++ interactions to see if there's some common pitfall there that I'm not aware of. Commented Sep 1, 2016 at 7:36
  • 1
    What is SomeStruct, does it have the exact same layout in C# and C++? Commented Sep 1, 2016 at 7:49
  • I added the structs' definitions in either language. Commented Sep 1, 2016 at 9:53

1 Answer 1

2

A solution to your problem can be to precede your declaration withe the following marshaling.

[return:MarshalAs(UnmanagedType.I1)]

This may happen because C defines bool as 4 bytes int and C++ defines it as 1 byte. C# team decided to use 4 byte bool as default during PInvoke because most of the system API function use 4 bytes values as bool. If you want to change this behavior you have to do it with marshaling specifying that you want to use 1 byte value. Also another solution can be to try changing the return type from bool to int, that should also fix the issue.

For more information, have a look at the answer mentioned here: C# DllImport with C++ boolean function not returning correctly

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.