2010-11-22 13 views
2

私はこの本当に単純なP/Invokeに完全に失敗しました。C#の単純な文字列を整列する

[System.Runtime.InteropServices.DllImport(
     "temp.dll" 
    )] 
    private static extern System.IntPtr parser_alloc(); 

    [System.Runtime.InteropServices.DllImport(
     "temp.dll", 
     CharSet = System.Runtime.InteropServices.CharSet.Ansi 
    )] 
    private static extern void parser_add_file(
     System.IntPtr p, 
     [MarshalAs(UnmanagedType.LPStr)]string f, 
     [MarshalAs(UnmanagedType.LPStr)]string s); 

    [System.Runtime.InteropServices.DllImport(
     "temp.dll" 
    )] 
    private static extern void parser_free(
     System.IntPtr p); 

    [System.Runtime.InteropServices.DllImport(
     "temp.dll" 
    )] 
    private static extern void parser_emit_results(
     System.IntPtr p); 

    [System.Runtime.InteropServices.DllImport(
     "temp.dll", 
     CharSet = System.Runtime.InteropServices.CharSet.Ansi 
    )] 
    private static extern void parser_file_updated(
     System.IntPtr p, 
     [MarshalAs(UnmanagedType.LPStr)]string f, 
     int offset, 
     int added); 

オブジェクトを作成すると問題はないようです。しかし、私がparser_add_fileを呼び出そうとすると、ランタイムは私に不一致の署名があることを知らせます。これは私の既存のC++コードです:

class Parser { 
public: 
    void add_file(std::string filename, std::string source) { 
     std::cout << "add_file | " << filename << " | " << source << "\n"; 
    } 
    void clear_contents() { 
     std::cout << "clear_contents\n"; 
    } 
    void emit_results() { 
     std::cout << "emit_results\n"; 
    } 
    void file_updated(std::string filename, int offset, int added) { 
     std::cout << "file_updated | " << filename << " | " << offset << " | " << added << "\n"; 
     // added should be negative to signify removing 
    } 
    Parser() { 
     std::cout << "I made a Parser!\n"; 
    } 
}; 

extern "C" __declspec(dllexport) Parser* parser_alloc() { 
    return new Parser; 
}; 

extern "C" __declspec(dllexport) void parser_add_file(Parser* p, const char* filename, const char* string) { 
    p->add_file(filename, string); 
} 

extern "C" __declspec(dllexport) void parser_free(Parser* p) { 
    delete p; 
} 

extern "C" __declspec(dllexport) void parser_emit_results(Parser* p) { 
    p->emit_results(); 
} 

extern "C" __declspec(dllexport) void parser_file_updated(Parser* p, const char* filename, int offset, int added) { 
    p->file_updated(filename, offset, added); 
} 

私はP /呼び出しをスキップして、この仕事のためにC++/CLIに行くべきでしょうか?

答えて

1

私は手動で呼び出し規約をcdeclに設定しなければならなかったことがわかります。デフォルトはstdcallです。

0

C++ソースにアクセスできる場合は、C++宣言レベルで呼び出し規約を変更することができます。以下は、私が書いたライブラリの関数例です:

int _stdcall GeoConvertLatLongToUTM(double latitude, double longitude, char *szOutput) 
関連する問題