I am trying to invoke a C API of Nvidia Omniverse from my .netcore based application.
It is an API to upload a file. You can find the contract here. https://docs.omniverse.nvidia.com/kit/docs/client_library/latest/_build/docs/client_library/latest/function_group__file_1gab649e472ef2238a89c4213357b1d5598.html#exhale-function-group-file-1gab649e472ef2238a89c4213357b1d5598
I don't have enough experience with C so I am not able to invoke this API.
My data is coming from another server as HttpContent.
I have written this code so far but my application crashes when omniClientWriteFileEx API is hit. Approach 1:
public class test
{
[DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)]
static extern ulong omniClientWriteFileEx(string url, OmniClientContent content, IntPtr userData, IntPtr callback, string message);
public async Task UploadUsingCApiAsync(string url, HttpContent httpContent)
{
var data = await httpContent.ReadAsByteArrayAsync();
var content = new OmniClientContent
{
Buffer = content,
Size = content.Length
};
omniClientWriteFileEx(url, content, IntPtr.Zero, IntPtr.Zero, "");
}
private struct OmniClientContent
{
public int Size;
public Byte[] Buffer;
}
}
Approach 2
public class test2
{
[DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)]
static extern ulong omniClientWriteFileEx(string url, OmniClientContent content, IntPtr userData, IntPtr callback, string message);
public async Task UploadUsingCApiAsync(string url, HttpContent httpContent)
{
var data = await httpContent.ReadAsByteArrayAsync();
var content = await dssHttpContent.ReadAsByteArrayAsync();
var buffer = Marshal.AllocHGlobal(content.Length);
Marshal.Copy(content, 0, buffer, content.Length);
var content = new OmniClientContent
{
Buffer = buffer,
Size = content.Length
};
omniClientWriteFileEx(url, content, IntPtr.Zero, IntPtr.Zero, "");
}
private struct OmniClientContent
{
public int Size;
public IntPtr Buffer;
}
}
I am able to invoke other APIs of this library where datatypes as primitive but this one involves a buffer.
The docs say:
So you can't just give it an array, because the marshaller will unpin it after the end of the call. You need to create your own buffer, and marshal in the data yourself.
First, declare all the PInvoke as follows. Note that you are missing
CharSet.Ansideclarations, and you need the callback definition.The third value in
OmniClientContentis a callback to free the buffer.Then you can do