Pergunta

I am writing a C# code, and there is a code that needs calling an unmanaged C++ library.

The signature in the library's header is like this

bool GetValueFromFile(char* sPathToFile, char* &sResult);

What signature should I translate this in C#? I tried:

bool GetValueFromFile(string filePath, ref string result)

But it does not work. There is no exception and the return value is true. But the string result stays null. It is the same for out string result or StringBuilder result.

I use Marshal.GetDelegateForFunctionPointer to get the function pointer as delegate.

Foi útil?

Solução

You can handle a reference to a pointer pretty much like a pointer to a pointer, at least as far as P/Invoke is concerned.

I think you will probably need to use an IntPtr for the sResult parameter, along with either Marshal.PtrToStringAnsi() or Marshal.PtrToStringAuto(), but it's a bit difficult to say without knowing whether the C/C++ function allocates the string memory or not.

If it works, you will probably still need to free the memory (after getting the string) using Marshal.FreeCoTaskMem() or Marshal.FreeHGlobal(), but again this is impossible to know for sure without knowing what the C/C++ function does.

NOTE: If using an IntPtr to get an output value, you will need to use out result or ref result.

Outras dicas

You'll need to pass a pointer by reference. Assuming that sResult is passed from native to managed, i.e. that it has out semantics, here's the signature:

bool GetValueFromFile(string filePath, out IntPtr result);

Once you've called this you will need to convert it to a string:

IntPtr resultPtr;
if (GetValueFromFile(filePath, out resultPtr))
    string result = Marshal.PtrToStringAnsi(resultPtr);

It's not clear who is responsible for freeing the memory that the native code allocates. Presumably that is documented somewhere and you already know how to handle that issue.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top