Importing functions from custom DLLs

From VRwiki
Jump to: navigation, search

To use a custom C function in XVR you have to create a DLL and import it in XVR.

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