修改从C#传递给DLL的结构的值

时间:2012-07-03 19:40:21

标签: c# dll struct marshalling

我正在尝试做两件事:从C dll函数获取返回值,并使用相同的函数修改传递给它的结构的1个成员。经过多次实验,我能够得到函数返回一个值,但我仍然无法让它将修改后的值返回给C#代码;值保持(未修改)为0。 我尝试了很多变化(参考,[进,出]等)无济于事

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 个答案:

答案 0 :(得分:2)

您的进口申报是错误的 在你的情况下设置CharSet没有任何意义(本机函数声明中没有字符串参数) 如果要传递类实例,则必须抛弃ref / out(通过引用传递类) 主要观点:extern "C" __declspec( dllexport )表示CallingConvention.Cdecl

<强>更新即可。这是完整的工作代码示例:
C ++(header):

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