Hello, I am working on a school project that needs to import a third party dll into my unity project. I am completely new to this(scripting, using api…) and I am looking for some advice.
First, I do not have the source code of the dll, all I know is it is a C-language Win32 dll created in Microsoft Visual Studio. I do have API.h which it only contains struct and enum types (wrote in return status).
By researching on the internet, the only method to I found to use the API is to use System.Runtime.InteropServices and DllImport. The examples I found are all int/float/void return type of functions and I do not know how to call struct and enum.
The best case scenrio I would imagine is to import the whole namespace and then I could just include that in c# script and have access to all vars and methods, is that possible? If not, what options do I have to use this library?
Here is the example header file for the API:
namespace API
{
extern "C"
{
typedef enum
{
noError = 0,
errorNotConnect = 101,
.....
} ReturnStatus;
API ReturnStatus SearchDevice(int* num, int id[], char serial[]);
........
}
}
Here is the code I tried which did not work:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
public class ConnectDevice : MonoBehaviour
{
[DllImport("API")]
public API api;
void Start()
{
Debug.Log("RS = " + api.ReturnStatus.noError);
}
}
Any help is appreciated, thanks!
First of all forget about any classes, objects or namespaces when it comes to native / managed interop. In order to call a C-style method that method need to be static in the API and you need to define that method in C# as an extern declaration using DllImport. DllImport has to be applied to the C# method declaration and you have to provide the dll name to that attribute.
C-style export does not really allow to export types that can be used on the C# side. You have to recreate the enum in C#. It’s also not clear how the data is used or how you need to provide them. Array types are generally vastly different between C# and C / C++. The same is true for pointers. The first tyoe parameters of the method you’ve shown are essentially pointers to an int in native memory. So it’s not clear what exact information you should pass here. Dealing with complex data types in interop can be tricky and should be avoided if possible. You should look into Marshalling which is a huge topic in its own. Variable length C-style arrays do not have any information about the size / length of the array. So the signature of the method seems a bit strange. Probably the “num” parameter may have something to do with the length of the other arrays, though without knowing the exact signature and how it works you can not call this method safely. Some arrays may be null terminated. However that doesn’t work for arrays of primitive types.
You may want to look into array marshalling. So without more information how the 3 parameters play together it’s impossible to create the proper extern definition in C#.
Here’s a generic example binding that just passes 3 native pointers.
public enum ReturnStatus
{
noError = 0,
errorNotConnect = 101,
// [ ... ]
}
[DllImport("YourDLLName.dll")]
public static extern ReturnStatus SearchDevice(IntPtr num, IntPtr id, IntPtr serial);
1 Like