1

セットアップ

以下に定義されているネイティブ関数を持つPDFAPIがあります。

typdef void* PDF_DOCUMENT;
unsigned long PDF_GetMetaText(PDF_DOCUMENT document,
                              const char tag, 
                              void* buffer, 
                              unsigned long bufferlen)

//Calling it "natively" in C++/CLI function to get the PDF Creator tag
WCHAR result[32];
void* pdoc = PDF_LoadDoc("C:\test.pdf");
int numChars = PDF_GetMetaText(pdoc, "Creator", result, 32);
PDF_CloseDoc(pdoc);

C ++ / CLIラッパー関数で上記のコードを呼び出すと、正しい文字列が返されますが、PDF_CloseDocを呼び出すとAccessViolationExceptionがスローされます。WOOPS。ドキュメントのポインタをpin_ptrするのを忘れました。

問題

pin_ptr pdocを実行すると、これらのネイティブ関数を正常に呼び出すことができますが、PDF_GetMetaTextが返されるときに、バッファに文字列が含まれなくなります。

String^ Wrapper::GetCreator(String^ filename)
{
   WCHAR buffer[32];
   void *pdoc = PDF_LoadDoc(SystemStringToCStr(filename));
   pin_ptr<void*> p = &pdoc; //added
   int numPages = PDF_GetMetaText(p, "Creator", buffer, 32);
   PDF_CloseDocument(p); //doesnt crash, but at this line buffer is an empty string

   return gcnew String(buffer);
}

また、buffer [0]を固定しようとしましたが、GetMetaTextでアクセス違反の例外が発生します。

質問

GetMetaTextで何が起こっているのかわからないので、pdocに何が起こっているのかわかりません。上記のコードに対する提案はありますか?

4

1 に答える 1

2

これは意味がありません。管理対象オブジェクトのみを固定できます。PDF_LoadDoc()の戻り値は、私には管理対象オブジェクトのようには見えません。結果についても同じことが言えます。これは管理対象ではなくarray<WCHAR>、スタックフレームに割り当てられる単なるバニラC配列です。残念ながら、pin_ptr<>はこれについて文句を言いません。

結果の配列は、コードがスタックフレームを踏みつけている場合にのみ、「空」になる可能性があります。これは、最初の要素にデータブレークポイントを設定することで診断できます。Fwiw、SystemStringToCStr()は候補のように見えます。これは、ネイティブ文字列のバッファをどこかで解放しないと機能しません。もう1つの候補は、PDFAPI関数宣言です。ESPレジスタの値に注意し、変化しないことを確認してください。その場合、適切な呼び出し規約がないため、スタックのバランスが崩れます。これは通常、DLLエクスポートの場合は__stdcallです。

于 2010-10-28T19:13:43.057 に答える