Изменение значения структуры, передаваемой в DLL из C#


Я пытаюсь сделать 2 вещи: получить возвращаемое значение из функции dll C и заставить эту же функцию изменить 1 из членов структуры, которая передается ему. После долгих экспериментов мне удалось заставить функцию возвращать значение, но я все еще не могу заставить ее возвращать измененное значение в код C#; значение остается (неизмененным) как 0. Я перепробовал множество вариантов (ref, [In, Out] и т. д.) безрезультатно

using System;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;

namespace Vexing.Problem{
    public class myIdx : VexingObject {
        public myIdx(object _ctx) : base(_ctx) { }
        private IPlotObject plot1;
    [StructLayout(LayoutKind.Sequential)] 
    public class PLEX { public int yowser; }

    [DllImport("my.dll", CharSet = CharSet.Unicode)]
    public static extern int cFunction(
               [MarshalAs(UnmanagedType.LPStruct)] PLEX mPlex);

    PLEX a;
    protected override void Create() { a = new PLEX(); }
    protected override void CalcBar() {
        int mf = cFunction(a);
        plot1.Set(a.yowser); }
}}

// pertinent c dll code
typedef struct s_plex { int yowser;} cplex;

extern "C" __declspec( dllexport )  
int cFunction(cplex *Cplex){ Cplex->yowser = 44; return 1;}
1 3

1 ответ:

Ваша декларация об импорте неверна.
Установка CharSet в вашем случае не имеет никакого смысла (в объявлении собственной функции нет строковых параметров).
Если вы хотите передать экземпляр класса, ref / out также должен быть выброшен (классы передаются по ссылке).
И главное: extern "C" __declspec( dllexport ) означает CallingConvention.Cdecl.

Обновление . Вот полный пример рабочего кода:
C++ (заголовок):

struct CStruct
{
    int myField;
};

extern "C" __declspec( dllexport ) int MyFunction(CStruct *pStruct);

C++ (код):

int MyFunction(CStruct *pStruct)
{
    pStruct->myField = 100;
    return 1;
}

C#:

[StructLayout(LayoutKind.Sequential)]
class MyStruct
{
    public int myField;
};

class Program
{
    MyStruct myStruct = new MyStruct();

    [DllImport("MyLib.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern int MyFunction(MyStruct pStruct);

    static void Main(string[] args)
    {
        var p = new Program();
        var result = MyFunction(p.myStruct);

        Console.WriteLine("Result: {0}, MyStruct.myField = {1}", result, p.myStruct.myField);
    }
}

Отпечатки пальцев:

Результат: 1, MyStruct.myField = 100