How to pass an object from Delphi 7 to a C++ dll? - c++

I am creating a DLL in C++ to be used in a Delphi 7 project, this dll will use OpenMP and will replace some methods that already exist in the project, this in order to hopefully get a speed up in the application.
One of the functions is defined like this:
function ReplaceFunction(chain:String;functionTE:TEFunction):string;
The object functionTE is declared like this,
TEFunction = class(TObject)
private
FFunctionName: string;
procedure SetFunctionName(const Value: string);
function GetFunctionNameCapital: string;
public
Handle:THandle;
Funcion:Pointer;
FileName:string;
ParamNumber:integer;
Description:string;
property FunctionNameCapital:string read GetFunctionNameCapital;
property FunctionName:string read FFunctionName write SetFunctionName;
end;
How can I pass an object of this class to the dll and use it?

How can I pass an object of this class to the dll and use it?
You cannot. Only Delphi code can consume Delphi classes. And even then, only code that uses the same instance of the runtime. Which requires runtime packages.
You'll need to expose the functionality in an interop friendly manner. Either plain C style functions, or a COM style interface are the obvious options.
And not only can you not pass that object, you also must not attempt to use Delphi native strings across an interop boundary. Again you need to use interop friendly types. For strings this includes C string (null-terminated arrays of characters) and the COM BSTR.

Related

Returning pointer to unmanaged class from C++/CLI wrapper which can be imported into C#

I have a C++ class that I need to create several instances of in a C# application. Apparently this means I'll need to make a C++/CLI wrapper as you can't import C++ classes into C#, but I've never used it before. The C++ class inherits from a base class which just contains several pure virtual functions, and no data. The DLL exports just one function which creates a new instance of the class and returns a pointer to the base class.
What C++/CLI type can be used to call that function and get the pointer to the C++ class, but which can also be imported into C#?
Thanks.
You don't need any special “C++/CLI type”, you should be able to call that function like from normal C++. But if you want to use the C++ class from C#, you really need to write C++/CLI managed wrapper class that you will be able to use from C#.
The managed wrapper class will contain a filed with a pointer to the unmanaged class. It will also contain the same members as the unmanaged class, that forward to their unmanaged equivalents.
For an example of how to do that, see How to: Wrap Native Class for Use by C# on MSDN.

JNI non-Java class members

I want to create a Java wrapper against some third-party library with C interface. The library operates on a complex Context entity which is essentially a C++ object (C++ is used internally in that library, but API is in pure C). It would be natural to wrap this entity into a class accessible from Java. For that, a pointer to Context should be stored somewhere.
I see two options to do this:
to declare a new member on java side (as long, for example) and convert it to pointer type inside JNI methods implementation
to declare a new member in JNI header (That might be illegal if Java relies on the size of structure it gerenated for me by javah)
All the tutorials on JNI are too simple to give me a hint on how to wrap a complex entities with Java classes, any links on more verbose documentation are appreciated.
I also want to know where it is appropriate to call Context destruction function (C++ destructor inside) I don't want to use Java finalize for that as Java don't favor finalize methods and I supect there is a way to define a destruction procedure on native side.

C++ DLL plugin interface

I'm planning on doing a C++ plugin interface ala How to create some class from dll(constructor in dll)?(с++)
but concerns have been raised that if the interface is used to create DLLs via MinGW or Borland and the DLL loader is compiled with MSVC++, there might be problems. Since the only exported function is declared extern "C" I fail to see why it would not work ?
Ideas ?
If you want to be compatible across compilers (and Release / Debug) and use C++, you need a little more effort.
Basically - you are allowed to pass basic datatypes, and pointer to pure virtual classes. These classes must not contain any data member, their destructor must not be public and they should not have overloaded functions.
Memory must not be allocated in one dll and released in another. This means no exceptions and you need some kind of reference counting or returning mechanism.
All methods inside pure virtual class (aka "Interface") must be marked with a call convention (I'd prefer stdcall).
Dynamic casts are not possible as well, so you might need some functionality in all your interfaces to do the trick (like QueryInterface in COM).
This works because most compiler on win32 try to be COM compatible and solve the same problems in a COM compatible way. For getting the first interface, you need a plain C function that is exported from the dll.
If you just use C functions and C data types, everything will work as well. But then you are limited to C without classes & inheritance.
I hope that helps.
Name mangling is not a problem:
1st: if you use C functions with C data types, everything is defined, there's no name mangling (exception: in VS with STDCALL, you need to remap the name to the "normal" C name via Linker directive)
2nd: Methods inside classes are not exported and thus not mangled. You call methods via pointer to pure virtual classes (aka "Interfaces"). This uses an offset and no name. You still can't use the destructor, as the position of the destructor inside the vtbl is not fixed as far as I know.
If you pass structs to functions / methods, be sure to fix the alignment. It is not defined across different compilers.
An idea could be using standard extern C function to create a ClassFactory. Have some convenction about a fixed ( or more ) entry point the dll must expose to be a valid plugin.

Custom COM Implementation?

I'm looking to implement a custom implementation of COM in C++ on a UNIX type platform to allow me to dynamically load and link object oriented code. I'm thinking this would be based on a similar set of functionality that POSIX provides to load and call dll's ie dlopen, dlsym and dlclose.
I understand that the general idea of COM is that you link to a few functions ie QueryInterface, AddRef and Release in a common dll (Kernel32.dll) which then allows you to access interfaces which are just a table of function pointers encapsulated with a pointer to the object for which the function pointers should be called with. These functions are exposed through IUnknown which you must inherit off of.
So how does this all work? Is there a better way to dynamically link and load to object oriented code? How does inheritance from a dll work - does every call to the base class have to be to an exposed member function i.e private/protected/public is simply ignored?
I'm quite well versed in C++ and template meta-programming and already have a fully reflective C++ system i.e member properties, member functions and global/static functions that uses boost.
A couple of things to keep in mind:
The power of COM comes largely from the IDL and the midl compiler. It allows a verry succint definition of the objects and interfaces with all the C/C++ boilerplate generated for you.
COM registration. On Windows the class IDs (CLSID) are recorded in the registry where they are associated with the executable. You must provide similar functionality in the UNIX environment.
The whole IUnknown implementation is fairly trivial, except for QueryInterface which works when implemented in C (i.e. no RTTI).
A whole another aspect of COM is IDispatch - i.e. late bound method invocation and discovery (read only reflection).
Have a look at XPCOM as it is a multi-platform COM like environment. This is really one of those things you are better off leveraging other technologies. It can suck up a lot of the time better spent elsewhere.
I'm looking to implement a custom implementation of COM in C++ on a UNIX type platform to allow me to dynamically load and link object oriented code. I'm thinking this would be based on a similar set of functionality that POSIX provides to load and call dll's ie dlopen, dlsym and dlclose.
At its simplest level, COM is implemented with interfaces. In c++, if you are comfortable with the idea of pure virtual, or abstract base classes, then you already know how to define an interface in c++
struct IMyInterface {
void Method1() =0;
void Method2() =0;
};
The COM runtime provides a lot of extra services that apply to the windows environment but arn't really needed when implementing "mini" COM in a single application as a means to dynamically link to a more OO interface than traditionally allowed by dlopen, dlsym, etc.
COM objects are implemented in .dll, .so or .dylib files depending on your platform. These files need to export at least one function that is standardized: DllGetClassObject
In your own environment you can prototype it however you want but to interop with the COM runtime on windows obviously the name and parameters need to conform to the com standard.
The basic idea is, this is passed a pointer to a GUID - 16 bytes that uniquely are assigned to a particular object, and it creates (based on the GUID) and returns the IClassFactory* of a factory object.
The factory object is then used, by the COM runtime, to create instances of the object when the IClassFactory::CreateInstance method is called.
So, so far you have
a dynamic library exporting at least one symbol, named "DllGetClassObject" (or some variant thereof)
A DllGetClassObject method that checks the passed in GUID to see if and which object is being requested, and then performs a "new CSomeObjectClassFactory"
A CSomeObjectClassFactory implementation that implements (derives from) IClassFactory, and implements the CreateInstance method to "new" instances of CSupportedObject.
CSomeSupportedObject that implements a custom, or COM defined interface that derives from IUnknown. This is important because IClassFactory::CreateInstance is passed an IID (again, a 16byte unique id defining an interface this time) that it will need to QueryInterface on the object for.
I understand that the general idea of COM is that you link to a few functions ie QueryInterface, AddRef and Release in a common dll (Kernel32.dll) which then allows you to access interfaces which are just a table of function pointers encapsulated with a pointer to the object for which the function pointers should be called with. These functions are exposed through IUnknown which you must inherit off of.
Actually, COM is implemented by OLE32.dll which exposes a "c" api called CoCreateInstance. The app passed CoCreateInstance a GUID, which it looks up in the windows registry - which has a DB of GUID -> "path to dll" mappings. OLE/COM then loads (dlopen) the dll, calls its DllGetClassObject (dlsym) method, passing in the GUID again, presuming that succeeds, OLE/COM then calls the CreateInstance and returns the resulting interface to app.
So how does this all work? Is there a better way to dynamically link and load to object oriented code? How does inheritance from a dll work - does every call to the base class have to be to an exposed member function i.e private/protected/public is simply ignored?
implicit inheritance of c++ code from a dll/so/dylib works by exporting every method in the class as a "decorated" symbol. The method name is decorated with the class, and type of every parameter. This is the same way the symbols are exported from static libraries (.a or .lib files iirc). Static or dynamic libraries, "private, protected etc." are always enforced by the compiler, parsing the header files, never the linker.
I'm quite well versed in C++ and template meta-programming and already have a fully reflective C++ system i.e member properties, member functions and global/static functions that uses boost.
c++ classes can typically only be exported from dlls with static linkage - dlls that are loaded at load, not via dlopen at runtime. COM allows c++ interfaces to be dynamically loaded by ensuring that all datatypes used in COM are either pod types, or are pure virtual interfaces. If you break this rule, by defining an interface that tries to pass a boost or any other type of object you will quickly get into a situation where the compiler/linker will need more than just the header file to figure out whats going on and your carefully prepared "com" dll will have to be statically or implicitly linked in order to function.
The other rule of COM is, never pass ownership of an object accross a dynamic library boundary. i.e. never return an interface or data from a dll, and require the app to delete it. Interfaces all need to implement IUnknown, or at least a Release() method, that allows the object to perform a delete this. Any returned data types likewise must have a well known de-allocator - if you have an interface with a method called "CreateBlob", there should probably be a buddy method called "DeleteBlob".
To really understand how COM works, I suggest reading "Essential COM" by Don Box.
Look at the CORBA documentation, at System.ComponentModel in the sscli, the XPCOM parts of the Mozilla codebase. Miguel de Icaza implemented something like OLE in GNOME called Bonobo which might be useful as well.
Depending on what you're doing with C++ though, you might want to look at plugin frameworks for C++ like Yehia. I believe Boost also has something similar.
Edit: pugg seems better maintained than Yehia at the moment. I have not tried it though.
The basic design of COM is pretty simple.
All COM objects expose their functionality through one or more interfaces
All interfaces are derived from the IUnknown interface, thus all interfaces have
QueryInterface, AddRef & Release methods as the first 3 methods of their virtual
function table in a known order
All objects implement IUnknown
Any interface that an object supports can be queried from any other interface.
Interfaces are identified by Globally Unique Identifiers, these are IIDs GUIDs or CLSIDs, but they are all really the same thing. http://en.wikipedia.org/wiki/Globally_Unique_Identifier
Where COM gets complex is in how it deals with allowing interfaces to be called from outside the process where the object resides. COM marshalling is a nasty, hairy, beast. Made even more so by the fact that COM supports both single threaded and multi-threaded programming models.
The Windows implementaion of COM allows objects to be registered (the original use of the Windows registry was for COM). At a minimum the COM registry contains the mapping between the unique GUID for a COM object, and the library (dll) that contains it's code.
For this to work. DLLs that implement COM objects must have a ClassFactory - an entry point in the DLL with a standard name that can be called to create one of the COM objects the DLL implements. (In practice, Windows COM gets an IClassFactory object from this entry point, and uses that to create other COM objects).
so that's the 10 cent tour, but to really understand this, you need to read Essential COM by Don Box.
You may be interested in the (not-yet)Boost.Extension library.

Callback from a C++ dll to a delphi application

Application is written in delphi 2010 and the underlying dll is a C++ dll.
In ideal case, when your application is in C++; The dll makes a callback to an application when an event occurs. The callback is implemented through an interface. Application developers implements the abstract c++ class and pass the object to the dll. The dll will then make a callback to a member function of your implemented class. A classic callback pattern it is.
But how do I pass a delphi object to the dll for it to make a callback.
I wouldn't really call that ideal. It is selfish and short-sighted to make a DLL that requires its consumers to use the same compiler as the DLL used. (Class layout is implementation-defined, and since both modules need to have the same notion of what a class is, they need to use the same compiler.)
Now, that doesn't mean other consumers of the DLL can't fake it. It just won't be as easy for them as the DLL's designer intended.
When you say the callback is implemented through an interface, do you mean a COM-style interface, where the C++ class has nothing but pure virtual methods, including AddRef, Release, and QueryInterface, and they all use the stdcall calling convention? If that's the case, then you can simply write a Delphi class that implements the same interface. There are many examples of that in the Delphi source code and other literature.
If you mean you have a non-COM interface, where the C++ class has only pure virtual methods, but not the three COM functions, then you can write a Delphi class with the same layout. Duplicate the method order, and make sure all the methods are virtual. The Delphi VMT has the same layout as most C++ vtables on Windows implementations, at least as far as the function-pointer order is concerned. (The Delphi VMT has a lot of non-method data as well, but that doesn't interfere with the method addresses.) Just be sure you maintain clear ownership boundaries. The DLL must never attempt to destroy the object; it won't have a C++-callable destructor that the delete operator could invoke.
If you mean that you have an arbitrary C++ class that could include data members, constructors, or non-pure methods, then your task is considerably more difficult. Follow up if this is the case; otherwise, I'd rather not address it right now.
Overall, I'll echo Mason's advice that the DLL should use plain C-style callback functions. A good rule of thumb is that if you stick to techniques you see in the Windows API, you'll be OK. If you're not in control of how to interact with the DLL, then so be it. But if you can make the DLL's external interface more C-like, that would be best. And that doesn't mean you need to abandon the C++-style interface; you could provide two interfaces, where the C-style interface serves as a wrapper for your already-working C++style interface.
You can't pass a Delphi object to C++, at least not without a very good understanding of how the object model works at the binary level. If you need callbacks, do them using C types only and plain functions and procedures (no methods) and you should be fine.