Closed mgravell closed 7 years ago
String handling in p/invoke is ugly... Sometimes it works, sometimes not... The safest way to do this, is using IntPtr and Marshal, as done for the error string of the same API using a public converter method and an internal p/invoke call:
[DllImport(NVML_API_DLL_NAME, EntryPoint = "nvmlErrorString")]
internal static extern IntPtr nvmlErrorStringInternal(nvmlReturn result);
/// <summary>
/// Helper method for converting NVML error codes into readable strings.
/// For all products.
/// </summary>
/// <param name="result">NVML error code to convert</param>
/// <returns>
/// String representation of the error.
/// </returns>
public static string nvmlErrorString(nvmlReturn result)
{
IntPtr ptr = nvmlErrorStringInternal(result);
string error;
error = Marshal.PtrToStringAnsi(ptr);
return error;
}
NVML library ist just "as is", so only a simple wrapper of the C++ header file and not tested. If the string value for device name doesn't work, all the other string parameters in other functions won't work, too.
Fixed all functions returning strings
The actual device name wouldn't come back; I'm not an expert in C/C++ bindings, so I don't know what the right attributes etc should be - but it works OK if you implement it as a
byte*
(and presumably asbyte[]
- untested). I ended up hacking it tobyte*
and using it this way, which worked for me:(as a side note, there's a
nvmlConstants::NVML_DEVICE_NAME_BUFFER_SIZE
(64) that it may be beneficial to expose in the API)