Изменение значения структуры, передаваемой в 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 ответ:
Ваша декларация об импорте неверна.
Установка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