Dynamicly loading a module (by LoadLibrary) if the module is already loaded in a process' address space does nothing more than incrementing module's internal reference count. If the module got loaded because it has been staticly linked with the exe, the reference count is -1 and LoadLibrary doesn't do anything other than returning a module handle.

As for the "Application.xxx" thing, there will be 2 application objects created if Forms.pas is compiled into both of the modules (this holds true for any unit with global data). If you however link with a runtime package (vcl.bpl), only 1 instance will be shared by all the modules which link with the package.

Next the original question. Entry point of the dll should be called when a process attaches to it so it should be called just once. Use LoadLibrary to load libraries which might not be available at runtime and are not crucial for the application to run properly (like plugins) or you have an alternative implementation for such case.

And finally to the code in your post - I think you are overcomplicating things. You are probably using RTTI to dynamicly get/set the values which is slow as hell. Besides such flexibility is of no use here because you do not store any dynamic data. A mesh must always have vertices otherwise it wouldn't be a mesh, right? I believe this can be applied to many object types used in a game engine. If you want efficient inter-module communication you have 3 possibilities. Use dlls + structures (records) in the good old C-way (like your "N3D_Mesh_GetVertexCount") - you cannot use Delphi's built-in types like strings or dynamic arrays nor its register calling convention if it is to be interoperable with other languages like C/C++/C#/etc. so you have to marshal data around. Then you can use delphi's packages which allow you to work like as if units from the package are staticly linked into the exe but they are in a seperate special dll - you can safely use Delphi's built-in types since packages can only be used from Delphi or C++ Builder. And finally you can use dlls + interfaces - you define an interface through which the host will communicate with the dll. For example you define an interface "IMesh" and a class "TN3DMesh = class(TInterfacedObject, IMesh)" and let the dll export a function "CreateMesh(Vertices: PVertexArray; VertexCount: Integer): IMesh" - the host calls the exported function from the dll, obtains an IMesh interface which it can then use to access data and call methods.

I hope this helps.