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

Popular posts from this blog

formatting - SAS SQL Datepart function returning odd values -

c++ - Apple Mach-O Linker Error(Duplicate Symbols For Architecture armv7) -

php - Yii 2: Unable to find a class into the extension 'yii2-admin' -