2011-06-19 6 views
1

これは、ネイティブCメソッドのシグネチャです。のPInvokeの問題

これは私がC#のからそれを呼び出す方法です:

byte[] arrayIn= Encoding.UTF8.GetBytes(source); 
uint arrayInSize = (uint)arrayIn.Length; 
byte[] arrayOut = new byte[100]; 
uint[] arrayOutSize = new uint[1]; 
arrayOutSize[0] = (uint)arrayOut.Length; 

fixed (byte* ptrIn = arrayIn, ptrOut = arrayOut) 
{ 
    if (nativeMethod1(ptrIn, arrayInSize, ptrOut, arrayOutSize)) 
    { 
     Console.WriteLine("True"); 
    } 
    else 
    { 
     Console.WriteLine("False"); 
    } 
} 

といくつかのDllImportコード

[DllImport(@"IcaCert.dll", EntryPoint = "CreateCert2", CallingConvention = CallingConvention.Cdecl)]<br> 
public unsafe static extern bool CreateCert2WithArrays(
     byte* data, uint dataSize,<br> 
     byte* result, uint[] resultSize); 

文書によると、ネイティブメソッドはarrayOutがarrayInに応じた値で満たさ返す必要があります。そのサイズが必要以上に小さい場合はfalseを返します。そうでなければ真。私はarrayOutに850要素が必要だと考えました。したがって、新しいbyte [100]配列を作成すると、関数はfalseを返すはずですが、常にtrueを返します。どうして?

+0

なぜあなたは安全でないコードを使用していて、修正しましたか?それはここでは必要ありません。 –

+0

しかし、私はバイト*ポインタを使用して、それは危険である必要がありますさらに、この部分のバイト* ptrIn = arrayInは固定されている必要があります。 – Sergey

+0

あなたは 'byte *'を使う必要はありません。私の答えは –

答えて

4

安全でないコードは必要ありません。ここで解決してください。標準P /マーシャラーを呼び出しますが、タスクまで以上のものです:

[DllImport(@"IcaCert.dll", EntryPoint = "CreateCert2", CallingConvention = CallingConvention.Cdecl)] 
public static extern bool CreateCert2WithArrays(
    byte[] arrayIn, 
    uint arrayInSize, 
    byte[] arrayOut, 
    ref uint arrayOutSize 
); 

byte[] arrayIn = Encoding.UTF8.GetBytes(source); 
uint arrayInSize = (uint)arrayIn.Length; 
uint arrayOutSize = 0; 

CreateCert2WithArrays(arrayIn, arrayInSize, null, ref arrayOutSize); 
byte[] arrayOut = new byte[arrayOutSize]; 
CreateCert2WithArrays(arrayIn, arrayInSize, arrayOut, ref arrayOutSize); 

私は、機能のプロトコルが何であるかを確実に知っていないが、そのような機能があればNULLを受信することができるようにするために、それは正常です出力配列のサイズは0です。

+0

私はそれが正常に動作することを知って、私の正常なarrayOutSizesでも動作します。しかし、私が好奇心を持っているのは、arrayOutSizeが必要以上に小さくなっても機能しない理由です。それはfalseを返しますが、そうではありません。私はC + +でそれをチェックし、arrayOutSizeが必要以上に小さい場合は常にfalseを返します。何も思いつきません。 – Sergey

+0

ネイティブコードが正しいです、私はjavaとC++でテストしましたが、C#は失敗します – Sergey

+0

Hansは言うとおり、元のコードは間違っていました。上のコードはそれを行う方法です。これから出発して前進する。 –

0

私はあなたが探している配列ではないと思います。これは、配列のサイズへのポインタであり、サイズの配列へのポインタではありません。これを試してみてください:

[DllImport(@"IcaCert.dll", EntryPoint = "CreateCert2", CallingConvention = CallingConvention.Cdecl)] 
public unsafe static extern bool CreateCert2WithArrays(
byte* data, uint dataSize, 
byte* result, ref uint resultSize); 

byte[] arrayIn= Encoding.UTF8.GetBytes(source); 

uint arrayInSize = (uint)arrayIn.Length; 
byte[] arrayOut = new byte[100]; 
uint arrayOutSize = (uint)arrayOut.Length; 
CreateCert2WithArrays (arrayIn, (uint) arrayIn.Length, arrayOut, ref arrayOutSize); 
uint[] arrayOutSize = new uint[1]; 
arrayOut = new byte[(int)arrayOut]; 
CreateCert2WithArrays (arrayIn, (uint) arrayIn.Length, arrayOut, ref arrayOutSize);