Well, because the interface system uses polymorphism, it''s going to call the inherited function isn''t it?
You have to remember that you''re unique, just like everybody else.
Dll Files
Quote: Original post by variantIf the entry points are fetched from a DLL, the main problem is understanding the mangled name.
I guess I mean correct entry points. It will probably compile, but in runtime, will calling the inherited methods correctly reference the dll code, or will it call the base classes implementation?
You can't fetch functions but just function pointers.
Inherited methods will be discriminated and called as expected, the problem is that if those methods are from a dll, then they are not methods. They are function pointers.
So, your method may be a container for a call to the dll-fetched function. This has some performance issues if you're in a performance path but saves code readability and safety quite a bit since the compiler will do most things for you.
This means a derived class will, in fact just redefine the internal pointers by fetching them differently.
The other method is to expose the pointers. This is probably faster and not necessarly bad but you lose some compiler helps such as automatic overriding (you'll have to do it yourself by fetching correct dll func) and some other aids.
It's still very difficult for me to understand if this is what you wanted because the problem is that, if you have functions then functions are not fetched from dlls. Function pointers can. It's a very small difference which you need to have pretty clear.
In fact,
CallToFunction();
C/C++ documntation say "()" is an operator.
The problem here is that I think the compiler won't allow you to get a pointer to func and assign them to a function.
Reasons:
The compiler knows all the functions. So, it may save their addresses in constant memory. It could also simply expand their addresses... something like
// ASM-like language, ipotetical, inspired from x86 and C.// Call to 'constant', compile-time funcCALL 0x05531779;// Call to a pointer to function// Get the pointer from constant memory (constant in the sense it's allocated from stack at compile-time, not necessarly constant in the sense of const). The pointer is stored in that memory address.MOVE 0x00145811, edx;// Now use pointer address to call a funcCALL edx;// In fact it's not so easy because of calling conventions, push/pops and stuff but the idea is that.
Do you understand why it does not work?
To make you sure I'm not speaking to the wind:
void Func1() {}void Func2() {}int main() { void (*pointerToFunc)(void) = Func2; Func1 = pointerToFunc; return 0;}
Compiled:
fetchFunc.cpp: In function `int main()':fetchFunc.cpp:10: error: assignment of function `void Func1()'fetchFunc.cpp:10: error: cannot convert `void (*)()' to `void ()()' in assignment
Previously "Krohm"
Quote: Original post by Krohm
If the entry points are fetched from a DLL, the main problem is understanding the mangled name.
Not really, you just export the interface fuctions within an extern "C" bracket. So:
extern "C"{ bool ReturnInterface( IInterface **ptr ); void DestroyInterface( IInterface **ptr );}
If at first you don't succeed, redefine success.
Quote: Original post by python_regious
Not really, you just export the interface fuctions within an extern "C" bracket. So:
So that?
Quote: Original post by Krohm
So, the idea was to add to C++ an "export" keyword. I has been told it was only recently introduced.
Basically, how to make a nice entrypoint in C++?
extern "C" {
// C thing here, so nice entripoints
// But no C++ nice features!
}
The keyword would avoid using C. As far as I know it would just bypass the name mangling scheme.
Problems: how are namespaces and member functions handled?
Anyway, even if mangled name is not a problem, the rest of the message still holds its issues.
Previously "Krohm"
Yes, you can't use the extern "C" if you try to export an entire class. However, you can use it to export interface creation/destruction routines, which is all you need.
If at first you don't succeed, redefine success.
Ok, I took a day to think at what you suggested.
I don't figure out.
There's probably something I'm misunderstanding from your post or maybe something related to a function of the extern "C" keyword I'm not aware of.
Could you please explain to me in a more lenghty discussion how can I do that? I still don't understand how to make namespace aliasing work and some related issues.
Thank you.
I don't figure out.
There's probably something I'm misunderstanding from your post or maybe something related to a function of the extern "C" keyword I'm not aware of.
Could you please explain to me in a more lenghty discussion how can I do that? I still don't understand how to make namespace aliasing work and some related issues.
Thank you.
Previously "Krohm"
Ok, I'll give you an example, as I think it'll be easier. I think this all ready came up further up in the thread though ( I could be totally missing the point ).
Header in DLL file, and application. (interface.h)
Header in DLL file, giving implementation of the interface we just defined, and the creation/destruction routines
I won't provide the implementation of CreateInterface and co, as it's very simple ( just create a SomeClass object using the IInterface pointer provided, or destroy it, depending on the function ).
Source file in the application:
I think it's all pretty self explanitory from that. You can use the SomeClass class through the IInterface ADT, and it all works pretty nicely ( and you only have to export the two interface creation/deletion functions ).
Now, with namespaces. I'm not really sure what you want to do with them? You want the exported functions to be in a namespace? If you want them in a namespace in the application, then thats a nobrainer, if you want to export them from the DLL and they're in a namespace, then the extern C keyword ( as far as I'm aware ), will just not export the namespace information. It really doesn't matter if SomeClass is in a namespace or not. I'm not too sure about the IInterface ADT, though, I don't think it does (I've used the interface classes in namespaces with no problems).
I think this is what you wanted to know, but I'm not sure. I should probably read the whole of this thread...
Header in DLL file, and application. (interface.h)
class IInterface{public: IInterface(){}; ~IInterface(){}; virtual void ExampleMethod() = 0; virtual void ExampleMethod2() = 0;};
Header in DLL file, giving implementation of the interface we just defined, and the creation/destruction routines
#include "interface.h"#ifdef WIN32#define dll_export __declspec( dllexport )#else#define dll_export#endifclass SomeClass : public IInterface{public: SomeClass(){}; ~SomeClass(){}; virtual void ExampleMethod(){ ... }; virtual void ExampleMethod2(){ ... };private:// any variables 'n' stuff};extern "C"{ dll_export bool CreateInterface( IInterface **ptr ); dll_export void DestroyInterface( IInterface **ptr );}
I won't provide the implementation of CreateInterface and co, as it's very simple ( just create a SomeClass object using the IInterface pointer provided, or destroy it, depending on the function ).
Source file in the application:
#include "interface.h"...// In some function somewhere... Load the DLL/so/whatever, and get the function pointers for CreateInterface and DestroyInterface...// Somewhere else.// To use the SomeClass object now, you need to use the CreateInterface function.IInterface *ptr = 0;if( !CreateInterface( &ptr ) ) Do error stuff// can now call member functionsptr->ExampleMethod();ptr->ExampleMethod2();// use DestroyInterface to delete the objectDestroyInterface( &ptr );
I think it's all pretty self explanitory from that. You can use the SomeClass class through the IInterface ADT, and it all works pretty nicely ( and you only have to export the two interface creation/deletion functions ).
Now, with namespaces. I'm not really sure what you want to do with them? You want the exported functions to be in a namespace? If you want them in a namespace in the application, then thats a nobrainer, if you want to export them from the DLL and they're in a namespace, then the extern C keyword ( as far as I'm aware ), will just not export the namespace information. It really doesn't matter if SomeClass is in a namespace or not. I'm not too sure about the IInterface ADT, though, I don't think it does (I've used the interface classes in namespaces with no problems).
I think this is what you wanted to know, but I'm not sure. I should probably read the whole of this thread...
If at first you don't succeed, redefine success.
Quote: Original post by python_regious
I think this is what you wanted to know, but I'm not sure. I should probably read the whole of this thread...
Yes, at least I have understood what you mean, thank you. Yes, I have the impression you should read all the stuff (this is why I usually don't post to long threads, I can understand something has gone away). In fact, finding the solution is harder than that because thread originator stated that it should really be C++.
Quote: Original post by Steve132
Can DLLs store classes and stuff like that?
Quote: Original post by python_regious#include "interface.h"#ifdef WIN32#define dll_export __declspec( dllexport )#else#define dll_export#endifclass SomeClass : public IInterface{public: SomeClass(){}; ~SomeClass(){}; virtual void ExampleMethod(){ ... }; virtual void ExampleMethod2(){ ... };private:// any variables 'n' stuff};extern "C"{ dll_export bool CreateInterface( IInterface **ptr ); dll_export void DestroyInterface( IInterface **ptr );}
I would have liked a more abstract example but it's fine anyway. As for the MS-specific stuff I won't say anything on it.
Quote: Original post by python_regious
I won't provide the implementation of CreateInterface and co, as it's very simple ( just create a SomeClass object using the IInterface pointer provided, or destroy it, depending on the function ).
Sorry, I still don't see the light. Those two functions are in standard C right? Then, 'new' is not there. How to simulate 'new'? I would malloc'ate some memory, mess up with pointers to initialize all my subfields manually. Uh-oh.
Problem 1:
I don't know if ANSI/ISO C/C++ spec forces or standardizes a way to allocate those data members. I.E. I have not a single way to really let the compiler know that ((byte*)this) is really an object-specific boolean referred in C++ code as myClass::boolean, ((byte*)this)+1 is a 32bit integer referred in C++ code as myClass::integer32.
Now, let's forget about those problems on alignment every platform have but I am pretty sure some compilers could swap the two arguments and then my offsets are pointing to garbage. Ack.
Problem 2:
Oh my god, I think I'll run away screaming when I'll have to initialize an object I have here called derived_t, because it's derived from base_t class and it also needs to be manually allocated an initialized. derived_t has a sub-field of type contained_t, which is utterly complicated.
I see the complexity is growing up pretty fast here. Considering it's easy to have errors in the offset computation, I'll find myself in hell before I'll realize it.
I still don't understand some implications of the idea, really.
Quote: Original post by python_regious
I think it's all pretty self explanitory from that. You can use the SomeClass class through the IInterface ADT, and it all works pretty nicely ( and you only have to export the two interface creation/deletion functions ).
It's not for me. You probably are so much more experienced than me that it looks so easy for you it doesn't even need to be said. For me, a thing like that is... out from my ideas.
Still, I am having bunches of allocated-on-stack variables. Having to do it with heap allocation, using the interfaces defined annoys me (that's what C++ was for I guess).
Quote: Original post by python_regious
Now, with namespaces.
Sorry, my fault. I am used to refer to scopes as "namespaces". I knew C++ effectively has a namespace feature so I should have avoided that.
I also admit I used very little the C++ "namespace" feature (hopefully I'll put some time on it soon) and I don't like it too much right now.
Quote: Original post by python_regious
if you want to export them from the DLL and they're in a namespace, then the extern C keyword ( as far as I'm aware ), will just not export the namespace information.
This is also the workings of the keyword as I know it and that's the problem since this could cause aliasing and collisions. This is not really a problem since I could just use a special syntax to declare the function, the problem is that the function will have to be implemented in C, which makes things complicated from my point of view.
Now, everything would go fine if I could put the declaration in C and the definition in C++ but I guess not a single compiler would like this hack.
The discussion is turning out to be pretty interesting however, I also would suggest to not poison out the thread anymore. It's beginning to be way too lenghty. I also see we are speaking about details so I suggest to continue our discussion privately though emails and then post only the neat results here.
In case someone wants to get the mails, I'll do something to allow this.
EDIT: ok, I see you don't have a mailto in your profile. That's bad. I have it avaiable. I guess you'll have to start the connection if you agree to that. I'll continue monitor the thread anyway for some days.
Previously "Krohm"
I haven't really got an email address I don't mind getting spammed anymore, so I chose not to display it. However, I think it's more beneficial to carry on this thread, as then others can also see what your problem is, and any possible solutions. If you really want to get hold of me, PM me.
The functions are exported using the C naming convention. Thats all. For clarity, this is whats inside the CreateInterface and DestroyInterface functions:
You *could* do this with malloc, but you'd have to call the constructor and destructor manually.
You *have* to use pointers, thats how polymorphism works.
Quote:
Sorry, I still don't see the light. Those two functions are in standard C right? Then, 'new' is not there. How to simulate 'new'? I would malloc'ate some memory, mess up with pointers to initialize all my subfields manually. Uh-oh.
The functions are exported using the C naming convention. Thats all. For clarity, this is whats inside the CreateInterface and DestroyInterface functions:
bool CreateInterface( IInterface **ptr ){ if( *ptr = new SomeClass ) return true; else return false;}void DestroyInterface( IInterface **ptr ){ delete *ptr; *ptr = 0;}
You *could* do this with malloc, but you'd have to call the constructor and destructor manually.
Quote:
Still, I am having bunches of allocated-on-stack variables. Having to do it with heap allocation, using the interfaces defined annoys me (that's what C++ was for I guess).
You *have* to use pointers, thats how polymorphism works.
It's not for me. You probably are so much more experienced than me that it looks so easy for you it doesn't even need to be said. For me, a thing like that is… out from my ideas.
What specifically do you not understand? Tell me and I'll explain it in more detail.
If at first you don't succeed, redefine success.
Quote: Original post by python_regious
The functions are exported using the C naming convention. Thats all.
I tested it. Looks like g++ is really able to have declarations in standard C and definitions is C++. Wow. I wasn't expecting that. I wonder how it figures out the correct binding and mangling. I'll check a MS compiler to see if it works it out.
Even if it works however, I am not yet sure it's safe to build a complex application on that trick. I'll have to check somebody who knows on compiler design. Maybe this is so used it effectively became supported widely. This could take some time but I'll try to figure it out since it's a very interesting aspect of compiler workings.
Quote: Original post by python_regious
You *have* to use pointers, thats how polymorphism works.
No, this is how runtime binding works. Sometimes I know I don't need runtime binding and I am safe with compile-time binding. I allocate without using pointers and that's fine. Still, I get the derived functionality.
Quote: Original post by python_regious
What specifically do you not understand? Tell me and I'll explain it in more detail.
The fact the compiler binds entrypoints declared in two different coventions is unclear. Before I was thinking this wasn't possible at all. Now I know this is possible, however I am not really aware of how much safe it is. More complex testing is definetly needed here. I won't be able to do it with simple tests because those may not be real scenarios.
However, I realize the fact trying it on a complex architecture takes some time.
I give up at that, I don't think I'll be able to test this with my technology in short times, I have priorities.
Previously "Krohm"
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement