3

私は2つのことをしようとしています:C dll関数から戻り値を取得し、同じ関数に渡される構造体のメンバーの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;}
4

1 に答える 1

3

輸入申告が間違っています。
あなたのケースで を設定し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

于 2012-07-03T20:26:11.957 に答える