Попытка вызвать функцию на C# из C Dll

Я написал простую функцию суммирования с помощью Rhapsody Developer на языке C и объявил ее как __declspec(dllexport) int Class_Sum_sum(Class_Sum* const me, int a, int b); в своем файле C. Я полный новичок в программировании на C#.

Моя программа на С# выглядит так:

using System.Runtime.InteropServices;


namespace Test1_C_Sharp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            int x = Win32.Class_Sum_sum(5, 8);
            textBox1.Text = x.ToString();
        }
    }

    public class Win32
    {
        [DllImport("CalcSum.dll", CharSet = CharSet.Auto)]
        public static extern int Class_Sum_sum(int a, int b);

    }

}

Когда я выполняю этот код, я получаю форму с текстовым полем и кнопкой «сумма», как и ожидалось, когда я нажимаю кнопку «сумма», возникает исключение, говорящее, что

Был обнаружен PInvokeStackImbalance

что на самом деле имеет смысл, потому что у меня есть три аргумента в моей функции C (Class_sum *, int, int), и я не знаю, как именно должен выглядеть первый аргумент в моем коде C#.

Кто-нибудь знает, как это сделать правильно?

РЕДАКТИРОВАТЬ: я смоделировал свой класс «Class_sum» в IBM Rhapsody, который переводится как struct в C. Фрагмент из моего H-файла выглядит следующим образом:

/*## class Class_Sum */
typedef struct Class_Sum Class_Sum;
struct Class_Sum {
    RiCReactive ric_reactive;
    int op1;        /*## attribute op1 */
    int op2;        /*## attribute op2 */
    int sum;        /*## attribute sum */
    /*#[ ignore */
    int rootState_subState;
    int rootState_active;
    int MainState_subState;
    /*#]*/ 
  ......
  ......
};

Rhapsody генерирует свои собственные функции и структуры, такие как, например, me, что переводится как this на языке ООП.


person Abel Tom    schedule 17.10.2017    source источник
comment
Нам нужно было бы увидеть детали Class_Sum, чтобы иметь возможность получить здесь полную помощь. Это нужно будет объявить в вашем коде С#, а экземпляр создать и передать функции. Другой причиной дисбаланса стека могут быть разные соглашения о вызовах — либо _cdecl, либо __stdcall — вам нужно убедитесь, что они совпадают.   -  person PaulF    schedule 17.10.2017
comment
Вам нужно будет изучить сортировку структур/классов c — попробуйте эти ссылки: docs.microsoft.com/en-us/dotnet/framework/interop/ & limbioliong.wordpress.com/2011/06/03/. С классами, содержащими простые типы, такие как int, double и т. д., это довольно просто, но если структуры содержат более сложные типы, такие как строки, массивы и другие классы, правильная сортировка может быть очень сложной. Есть ли особая причина, по которой вы хотите попробовать что-то настолько сложное?   -  person PaulF    schedule 17.10.2017
comment
Большое спасибо за идеи, в моей программе на C# я создал фиктивную структуру Class_sum, создал ее экземпляр (или, лучше сказать, объект) и передал этот экземпляр в качестве первого аргумента в вызове функции, и он работает, как и ожидалось.   -  person Abel Tom    schedule 17.10.2017
comment
@AbelTom, вам часто нужно вызывать неуправляемые функции из C#? Сортировка данных может стать довольно изнурительной по мере роста сложности. Есть лучшие альтернативы там. Например, ознакомьтесь с [C++/CLI] (codeproject.com/Articles/19354/). Марашаллинг данных встроен в него и происходит в фоновом режиме. Преобразование типов данных вне зависимости от сложности — это проще простого.   -  person Nik    schedule 31.10.2017


Ответы (1)


вам нужно указать третий параметр, и поскольку это указатель в С#, вы должны использовать слово ref

public static extern int Class_Sum_sum(ref Class_Sum parameterName,int a, int b)
person Abdulkarim Mak    schedule 17.10.2017