2012-04-11 10 views
0

ポインタparamsを使用して出力パラメータを取得するための適切なシグネチャ/マーシャル属性は何ですか?これまでのところ、私はこれを試してみました:Dll参照で単一の値を取得する方法

// Function to calculate the norm of vector. !0 on error. 
// int err_NormVec(int size, double * vector, double * norm) 
[DllImport("vectors.dll")] 
int err_NormVec(int size, double[] vector, ref double norm) 

以前のアプローチは、私はまたのIntPtr署名で、固定GCHandleを使用しようとしたC.から.NETに値をバックポップしません。

[DllImport("vectors.dll")] 
int err_NormVec(int size, double[] vector, IntPtr norm) 

public void doSomething() 
{ 
    double norm = 0; 
    // ... 
    GCHandle handle = GCHandle.Alloc(norm, GCHandleType.Pinned); 
    int status = err_NormVec(vector.Lenght, vector, handle.AddrOfPinnedObject()); 
    // ... clean gchandle, check status and so on 
} 

この場合、私はGCHandle.Targetの値を元に戻していますが、元の基準ではありません。どちらが迷惑です。私は、それだけではなく、自己の規範のintptrを固定することができるようにしたいと思います。

ポインタを使用して値を返す適切なシグネチャは何ですか? IntPtrをint値にするためのサポートされた方法はありますか?

+0

私はwin64を使用していることを忘れています。幸運にもwin32アプリで動作する悪い習慣をいくつか公開しました。 – fprades

+0

'err_NormVec'の実装(または少なくとも署名)を教えてください。出力パラメータとして使用するためにdoubleを固定する必要はありません。 'ref'で十分です。 –

+0

@エイズ:あなたは盲目ですか? – leppie

答えて

1

これは(それが必要として)私の作品:refキーワードを使用してdoubleを渡す

//C++ DLL (__stdcall calling convention) 
extern "C" __declspec(dllexport) void Foo(double *result) { 
    *result = 1.2; 
} 

//C#  
class Program 
{ 
    [DllImport("Snadbox.dll", CallingConvention=CallingConvention.StdCall)] 
    static extern void Foo(ref double output); 

    static void Main(string[] args) 
    { 
     double d = 0;   
     Foo(ref d); 

     Console.WriteLine(d); // prints "1.2"   
    } 
} 

で十分です。だから、私は実装に何か間違った(または誤解された)ことがあると信じるように導かれる。あなたは私たちのために実装を投稿できますか?

また、デフォルトの呼び出し規約(cdecl)を使用してC++バージョンを構築しているかもしれませんが、.NETではStdCallが使用されています。あなたはこれらのラインナップを確実にしましたか?混在しているとクラッシュする可能性がありますが、保証はありません。例えば、私の例では、C++側をcdeclに変更すると、outパラメータは0として読み返されます。

+0

実装は重要ではありませんが、これは単なる例であり、実際は複雑なライブラリです。あなたが望むのであれば、int err_NormVec(int size、double [] vector、double * norm)(* norm = 0; for int i = 0; i fprades

+0

@ fprades.bbva:まあ、私は失礼だとは言いませんが、あなたの意見は、なぜこれが動作していないのか分かりません。私は、単純化された例がうまくいくことを示しているので、他の何かが間違っていて、あなたはそれが何であるかを知るための十分な情報を与えていない。また、あなたが私に与えたスニペットは、逆参照することなくポインタ自体に追加している間違ったものです。 –

+0

これも同様に動作すると予想されるものです。しかし何らかの理由で、x64ランタイムではこのトリックを行いません。奇妙なたぶん私は試行錯誤のすべてで何かを逃した。 – fprades

関連する問題