Prosody TiNG: Using the API DLL

This document explains how to use the API DLL in three different situations:

Don't forget that, if you don't want to use the DLL, and you can compile C code, you can link the API library directly as described in Prosody Guide - how to build applications to use Prosody.

Using the DLL via .h and .LIB files

If you have development tools which allow you to use .h files, such as Microsoft Visual Studio, or if you have another C or C++ compiler, or even if you are using some other language but it can interpret C header files, then you make your program refer to the appropriate header files (as documented in Prosody Guide - how to build applications to use Prosody) and link with the TiNG.LIB file.

Using the DLL via .h file but without the .LIB file

If your development tools cannot use Microsoft .LIB files, then you must use the DLL directly. If you are using C, C++, or another language which lets you use the .h files, then this is not very difficult. The significant difference from using the .LIB file is that you must find the DLL entry points with GetProcAddress. You can do that like this:


SM_REPLAY_START_FN *sm_replay_start_ptr;

int prepare_TiNG_dll(void)
{
 HANDLE dll = LoadLibrary("TiNG.DLL");
 if (!dll) {
 	// handle error
 	return 1;
 }
 	// find all necessary functions
 sm_replay_start_ptr = GetProcAddress(dll, SM_REPLAY_START_NAME);
 if (!sm_replay_start_ptr) {
 	// handle error
 	return 1;
 }
 	... etc
 return 0;
}

	... code to call sm_replay_start() 
		assuming prepare_TiNG_dll() has already been called ...

	SM_REPLAY_START_PARMS rp;
	memset(&rp, 0, sizeof(rp));
	rp.channel = ...;		// set fields in 'rp'
	rp.... = 
	rp.... = etc
	r = (*sm_replay_start_ptr)(&rp);
	if (r) {
		// handle error


Every API function, sm_whatever(), has a typedef, SM_WHATEVER_FN, which allows you to declare a pointer to that function with the correct prototype.

The name used by the DLL is not simply the API function name. The name exported by the DLL also contains type information about the parameters expected by the function. This ensures that if the DLL is replaced with one in which the function parameters are different (for example, because an enhancement added an extra option field) then you can't accidentally call the function with the wrong parameters. The correct name is provided as a #defined string, with the correct name for API function sm_whatever being defined as SM_WHATEVER_NAME. If GetProcAddress fails to find this name in the DLL, this is most likely because the DLL it is searching is incompatible with the .h files used when building the application.

Using the DLL directly with neither .h nor .LIB files

If your development environment cannot use .h files, then you can still use the DLL directly, but it's a lot more work. You'll need to do this sequence of steps for each API function you want to handle. To illustrate, we'll look at how you would call sm_replay_start().

As you can see, this is a rather laborious process, because you have to interpret the .h files yourself. Once you've done this, your code will be compatible with future versions of Prosody TiNG, until there is a modification to one of the API functions you are using. When that happens, you will find that the attempt to locate the API function in the DLL fails. Fortunately, fixing this is much simpler than the original effort required to build the interface. Find what has changed and modify three parts of your code: the construction of the parameters, the name being looked up, and the interpretation of the results.