Hi all,
I've been experimenting with creating a dynamic library from my game engine in the last couple of days. The reason is some developers are interested in my game engine, but would rather use it with C/C++ or C#.
And the more important reason is that I have the course "Game Development" this semester at school where we have to use Horde3D and C++. For our final project I want to use my own sprite and font manager since Horde3D's built-in overlays are not really satisfying (just supports stretchting; no rotating, coloring or alpha) for my purposes and I really would love to have TTF support in my game instead of just the one TGA font that comes with the default project we have to use.

My plan is to flatten down my object-orientiented design so it can be used C or C# and then create classes on the top of that for C++ and C#.
I already tried porting the classes I needed from Object Pascal to C++ which unfortunately didn't work as planned and I hope creating a dynamic library and writing a C header would be much easier and less painful.

Allright, generating the library works without any problems, but when I try to access to the library with C# or C I get some strange results.

Let's take this code for example:
[pascal]
library SDLTestLib;

uses
SDL;

var
MainSurface: PSDL_Surface;

procedure Initialize();
begin
SDL_Init(SDL_INIT_VIDEO);
end;

procedure Finalize();
begin
SDL_Quit;
end;

procedure CreateWindow(Width: Integer; Height: Integer; BPP: Integer);
begin
MainSurface := SDL_SetVideoMode(Width, Height, BPP, SDL_SWSURFACE);
if not Assigned(MainSurface) then WriteLn('Something isn''t right here.');
end;

procedure SetWindowCaption(Caption: PChar);
begin
SDL_WM_SetCaption(Caption, Caption);
end;

procedure Flip;
begin
SDL_Flip(MainSurface);
end;

exports
{$IFDEF DARWIN} {OS X entry points}
Initialize name '_Initialize',
Finalize name '_Finalize',
CreateWindow name '_CreateWindow',
SetWindowCaption name '_SetWindowCaption',
Flip name '_Flip',
{$ENDIF}
Initialize,
Finalize,
CreateWindow,
SetWindowCaption,
Flip;

end.
[/pascal]

My C header:
Code:
#ifndef _SDLTESTLIB_H_
#define _SDLTESTLIB_H_

#ifdef __cplusplus
extern "C"
{
#endif

extern void Initialize();
extern void Finalize();
extern void CreateWindow(int Width, int Height, int BPP);
extern void Flip();
extern void SetWindowCaption(char* caption);

#ifdef __cplusplus
}
#endif

#endif /* _SDLTESTLIB_H_ */
My C# file:
Code:
using System;
using System.Runtime.InteropServices;

public class SDLTestLib {
 
 const string ElysionLibName = "SDLTestLib.dll";

 [DllImport(ElysionLibName, EntryPoint="Initialize",
       CallingConvention=CallingConvention.StdCall)]
       public static extern void Initialize();
 
 [DllImport(ElysionLibName, EntryPoint="Finalize",
       CallingConvention=CallingConvention.StdCall)]
       public static extern void Finalize();

 [DllImport(ElysionLibName, EntryPoint="Flip", 
       CallingConvention=CallingConvention.StdCall)] 
       public static extern void Flip();
 
 [DllImport(ElysionLibName, EntryPoint="CreateWindow",
       CallingConvention=CallingConvention.StdCall)]
       public static extern void CreateWindow(int Width, int Height, int BPP);
 
 [DllImport(ElysionLibName, EntryPoint="SetWindowCaption", 
       CallingConvention=CallingConvention.StdCall)] 
       public static extern void SetWindowCaption(string caption);

 public static void Main()
 {
  bool done = false;
 
	Initialize();
	Console.WriteLine("SDL initialized.");
 
	CreateWindow(640, 480, 16);
	Console.WriteLine("Window created.");
  
  while (!done)
  {
  	Flip();	
  }
	
	Finalize();
 }
}
The C# version won't work and terminates with an access violation when calling the Flip-procedure. The C version works, but assumes the Bits value as the height.
Oddly enough, if I change the code to interface with GLFW instead of SDL, the C# version works, but assigns the height value to the width.

I'm using FreePascal 2.4.0/2.4.1, tested with Windows XP (virtual machine) and Windows Vista.
Anyone had similar problems? What am I doing wrong? When writing a pascal header for C-DLL, you need something like
Code:
{$MINENUMSIZE 4}
{$PACKRECORDS C}
{$H+}
{$MACRO ON}
in the Pascal header. Do I need something similar in my Pascal library or in C/C# header? Is there something so obvious, I may have overlooked it?