pinvoke - Calling a unmanaged C method with a const char** argument from managed C# code -
pinvoke - Calling a unmanaged C method with a const char** argument from managed C# code -
i know when calling unmanaged method accepting char* argument c#, possible pass stringbuilder , have unmanaged c code modify it. have know size info want set stringbuilder, can pass buffer of right size. have found many threads helping this.
however, have c method accepts char** argument.
this allows methods check_if_encrypted
(shown below) provide malloc
'd error messages without calling method having know how much space allocate error message buffer, using next code in check_if_encrypted
: *strthecharstarstarargument = strlocalmallocderrormessage
, , calling passing &strerrormessage
strerrormessage
char*
what dllimport signature should used such method in c#?
for example, have next c code:
header:
extern __declspec(dllexport) keyfile *create_source_key_file_from_path(char *strpath); extern __declspec(dllexport) int check_if_encrypted(keyfile *kfsourcekey, int ktsourcekeytype, const char **strerrormessage);
main code:
keyfile *create_source_key_file_from_path(char *strpath) { /* snip */ } int check_if_encrypted(keyfile *kfsourcekey, int ktsourcekeytype, const char **strerrormessage) { /* snip */ char* strlocalerrormessage = (char*)malloc(sizeof(char)*17); strcpy(strlocalerrormessage,"this error"); *strerrormessage = strlocalerrormessage; /* snip */ } /* snip */ int main(int argc, char *argv[]) { keyfile *kfsource; char *strerrormessage; const char **strerrormessagep = &strerrormessage; int intisencrypted; kfsource = create_source_key_file_from_path("test.dat"); intisencrypted = check_if_encrypted(kfsource,0,strerrormessagep); if (strerrormessage != null) { /* handle error here. */ } else if (intisencrypted == 1) { /* handle encrypted file here. */ } else { /* handle unencrypted file here. */ } }
how effort @ replicating main method in c# using check_if_encrypted unmanaged method, has resulted in accessviolationexception (attempted read or write protected memory...) when calling check_if_encrypted.
[dllimport("ppkconverter.exe", setlasterror = true, callingconvention = callingconvention.cdecl, charset=charset.ansi)] public extern static intptr create_source_key_file_from_path([marshalas(unmanagedtype.lpstr)] stringbuilder strpath); [dllimport("ppkconverter.exe", setlasterror = true, callingconvention = callingconvention.cdecl, charset = charset.ansi)] public extern static int check_if_encrypted(intptr kfsourcekey, int ktsourcekeytype, [marshalas(unmanagedtype.lpstr)] ref stringbuilder sberrormessage); [stathread] public static void main(string[] args) { stringbuilder sbpath = new stringbuilder(@"test.dat"); stringbuilder sberrormessage = new stringbuilder(); intptr ipkeyfile = create_source_key_file_from_path(sbpath); // works int intisencrypted = check_if_encrypted(ipkeyfile, 0, ref sberrormessage); // throws exception. /* snip */ }
i think due utilize of ref stringbuilder
in dllimport signature beingness incorrect. should used instead?
thanks
the string unmanaged code returns caller allocated phone call malloc
. such p/invoke framework not capable of deallocating it. need export deallocator avoid leaks. in order phone call function using p/invoke you'll need marshalling manually.
[dllimport("ppkconverter.exe", callingconvention = callingconvention.cdecl)] public extern static int check_if_encrypted( intptr kfsourcekey, int ktsourcekeytype, out intptr sberrormessage );
convert intptr
returned in sberrormessage
string phone call marshal.ptrtostringansi
. , mentioned above need pass sberrormessage
deallocator avoid leaking.
i removed setlasterror = true
because uncertainty unmanaged function phone call setlasterror
.
since create_source_key_file_from_path
receives string input should declare this:
[dllimport("ppkconverter.exe", callingconvention = callingconvention.cdecl, charset=charset.ansi)] public extern static intptr create_source_key_file_from_path(string strpath);
are sure should linking functions in .exe file?
i wonder whether wise have unmanaged code allocate strings malloc
. forces export deallocator. might improve asking caller allocate memory. or if have allocate in unmanaged code, utilize shared heap com heap. way c# marshaller can deallocate memory.
c# pinvoke unmanaged access-violation
Comments
Post a Comment