Importing functions from custom DLLs
From VRwiki
To use a custom C function in XVR you have to create a DLL and import it in XVR.
Contents |
Create the DLL
When you create a C/C++ you have to use the __declspec(dllexport) keyword to tell the compiler to expose the function to extern calls, and if you want the linker to use the same name you give to the function you have to declare it in C fashion, with the extern "C" command.
extern "C" __declspec(dllexport) float myFunction(float *f, int n){ float a = 0; for(int i = 0; i < n; i++) a += f[i]; return a; }
Calling Convention: the Microsoft C/C++ compiler default convention is cdecl but the Windows APIs are exposed as stdcall convention. Apart the mangling of the name with _ and @ (e.g. _wipeme@12) there is an important difference in the way parameters are passed.
You can export only function no classes.
The website XVRTools contains a tool for generating a zip with a template Visual Studio Project and test XVR Project.
Import the DLL
XVR will use the library as an object, and the function will became the method of the object. To load the library use the CVmExternDLL object with the name of the library.
library = CVmExternDLL("myLib.dll");
a CVmExternDll object will be created, this object refert to your library, but now is empty and you have to add method with the __AddFunction(). In case the DLL is not available it generates a fatal error. Note that the DLL is not available also if DLL dependencies (other DLLs) are not available. Since Engine 150 optional second parameter of CVmExternDLL is a boolean that allows to specify to nicely return a void in case of missing DLL.
This function take the return value, the name of the exported function, and the type of the parameter.
library.__AddFunction(C_FLOAT, "myFunction", C_PFLOAT, C_INT);
Now you can use your function like a method of your library.
var a = [1.0, 2.0, 3.0]; var b; b = library.myFunction(a, 3);
b should be 6.
Since Engine 150 it is possible to define functions that have different names from the DLL function. For example if the DLL function is __EXT_myfx then it is possible to do:
library.__AddFunction(C_FLOAT, "__EXT_myfx","myFunction",C_PFLOAT, C_INT);
The first name is the name from the DLL
Note that it is also possible to automatically create AddFunction from a metadata function _meta using AutoExternDLL.
Type of parameter
the allowed type of parameter are:
- C_VOID
- void, used only for return value
- C_INT
- signed 32 bit int
- C_FLOAT
- 32 bit float
- C_DOUBLE
- 64 bit double
- C_PCHAR
- an array of char
- C_PSTR
- the same as above
- C_PINT
- an array of int
- C_PFLOAT
- a vector of float
- C_PDOUBLE
- an array of double (Since Engine 150)
- C_PFLOAT_1
- force the vector of float to be one element long
- C_PFLOAT_X
- same as above where X is a number from 1 to 16
Debugging an XVR DLL with IE 8
You might find problems in debugging your dll when using IE8 as XVR container; IE8 by default creates a frame process and several tabs processes, which may damp the debugger. In order to solve this, you have to edit your system registry as follows:
- create a DWORD value called TabProcGrowth in:
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main
- set the value to 0
For more details have a look at this article
