Thread: Pluggable C++ Code

  1. #1
    Registered User
    Join Date
    Aug 2009
    Posts
    198

    Pluggable C++ Code

    I am wondering if it is possible to have part of a program "pluggable": that you can change out a single source file for another one without recompiling or re-linking the rest of the program.

    Is this possible? If it is, does is come at the cost of slower execution?

  2. #2
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,472

    ?

    Not sure what you on about but unless you choose rebuild then the rest of the program remains as compiled in the current object file

  3. #3
    Registered User
    Join Date
    Aug 2009
    Posts
    198
    Quote Originally Posted by rogster001 View Post
    Not sure what you on about but unless you choose rebuild then the rest of the program remains as compiled in the current object file
    I am not sure what you meant by that.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It should be possible.
    If you are calling any methods inside the file that you swap out, you may or may not have to recompile or relink the rest of the program that depends on this file.
    You could also make a DLL out of the source and only swap this one out. You may have to relink, though, but it should be faster than compiling.

    I'm sure there are methods out there to avoid recompiling source files.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Aug 2009
    Posts
    198
    I the DLL method won't work for me because it exists only in Windows, but by program is exclusively written for and depends on *nix/X Window System.

    But maybe there is an equivalent thing in Linux.

    And I would still like to avoid relinking, because the point was that the user would have the executable to run, and they could swap out the pluggable part (doesn't matter if it has to be in binary or source form) to get different behavior, without having to use a compiler/linker.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Ah, well, why didn't you say so in the first place?
    Then you would use dynamic dll loading, or equivalent in Linux.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by MTK View Post
    I the DLL method won't work for me because it exists only in Windows, but by program is exclusively written for and depends on *nix/X Window System.

    But maybe there is an equivalent thing in Linux.
    "Perhaps UNIX has the functionality of something more complex than a pocket calculator."

    Uh, yes, of course it does ;-)

    Shared objects can be loaded and unloaded at runtime. See dlopen(), which is the moral equivalent of LoadLibrary() on Windows, and see dlsym(), which is the moral equivalent of GetProcAddress(). You will need to understand how to use function pointers.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  8. #8
    Registered User
    Join Date
    Aug 2009
    Posts
    198
    Quote Originally Posted by brewbuck View Post
    "Perhaps UNIX has the functionality of something more complex than a pocket calculator."

    Uh, yes, of course it does ;-)
    I didn't get it.

    Quote Originally Posted by brewbuck View Post
    Shared objects can be loaded and unloaded at runtime. See dlopen(), which is the moral equivalent of LoadLibrary() on Windows, and see dlsym(), which is the moral equivalent of GetProcAddress(). You will need to understand how to use function pointers.
    I'll see what dlopen() and dlsym() is.

    The windows equivalents don't help, I know nothing about Windows-specific programming.

  9. #9
    Registered User
    Join Date
    Aug 2009
    Posts
    198
    I made a small test program and got this compiler error:

    Code:
    $ g++ main.cpp
    /tmp/ccQ6aIip.o: In function `main':
    main.cpp:(.text+0x13): undefined reference to `dlopen'
    main.cpp:(.text+0x28): undefined reference to `dlsym'
    collect2: ld returned 1 exit status
    main.cpp:

    Code:
    #include <dlfcn.h>
    
    int main() {
    	void *dlhello = dlopen("pluggable.o", RTLD_LAZY);
    	dlsym(dlhello, "hello()");
    }

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    The dlopen() and dlsym() functions are located in a separate library called libdl. Add "-ldl" to the end of your compile command.

    Also, you will not be able to dlopen() a .o file. It needs to be a shared object.

    To convert a .o file into a shared object, do:

    Code:
    ld -shared -o myobject.so myobject.o
    Then use myobject.so instead of myobject.o

    Thirdly, you need to leave the "()" off the end of the function name.

    Fourthly, if you are using C++, the C++ function name will be mangled. Unless you want to directly pass a mangled name, you need to turn off mangling for that name by wrapping it in extern "C" {}
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  11. #11
    Registered User
    Join Date
    Aug 2009
    Posts
    198
    Quote Originally Posted by brewbuck View Post
    Also, you will not be able to dlopen() a .o file. It needs to be a shared object.

    To convert a .o file into a shared object, do:

    Code:
    ld -shared -o myobject.so myobject.o
    Then use myobject.so instead of myobject.o
    It gave me this error:

    Code:
    $ ld -shared -o pluggable.so pluggable.o
    ld: pluggable.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
    pluggable.o: could not read symbols: Bad value
    Quote Originally Posted by brewbuck View Post
    Fourthly, if you are using C++, the C++ function name will be mangled. Unless you want to directly pass a mangled name, you need to turn off mangling for that name by wrapping it in extern "C" (There where originally a pair of curly braces here, but the forum software kept complaining that is was source code without code tags around it)
    I don't really understand that.

  12. #12
    Registered User
    Join Date
    Aug 2009
    Posts
    198
    On this subject, I got curious if it's possible for a C++ program to call functions in a script (e.g. python, perl)?

  13. #13
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Quote Originally Posted by MTK View Post
    On this subject, I got curious if it's possible for a C++ program to call functions in a script (e.g. python, perl)?
    That's what I thought you were asking in the first place. You were asking if C++ could parse C++ source code at runtime, like a script, like in Python, Perl, PHP, and every other scripting language. The answer is no. Everything must be compiled beforehand. If you want to use shared objects, that is source code compiled beforehand, separately from the application.

    You hit the nail on the head, the solution is to have C++ load and call scripting languages. Python, Perl, LUA, PHP, Ruby, they have a C API to load/parse and call/create functions. You can find it on the respective websites.

    You would then compile your C++ application, create your Python script, the application loads it, runs it, and you can change your script without ever recompiling C++. However, you'll end up being required to put a lot of effort into it. Everything you want to do (access) from the script has to be explicitly declared in the C++ application. So there's a lot more initial work, but usually less in the long-run if it's a big project. Especially if you require some sort of scripting anyway, like in a game.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  14. #14
    Registered User
    Join Date
    Aug 2009
    Posts
    198
    No, I am not talking about parsing C++ code. I am talking about linking to precompiled source code during runtime.

    The interpreted language thing was kind of a side question, I was wondering if it would be a better alternative for my project than linking at runtime.

    This project is a little experimental GUI toolkit using Xlib, and I thought that linking to a seperate piece of code that draws the widgets during runtime would be a good way to implement themes.

    The idea is that the main C++ code manages the widgets, windows, and events, while the pluggable part does the drawing.

    Maybe there is a better way to do this, that's just all I could think of.
    Last edited by MTK; 11-28-2009 at 07:39 PM.

  15. #15
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Using scripting languages for GUI implementation is fairly common. Another common method is just using XML (create, configuration, events, etc). Smaller projects just use the GUI API directly (ala C++). Compiling them separately would certainly work for themes, like plugins, but seems impractical imo.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Extended ASCII Characters in an RTF Control
    By JustMax in forum C Programming
    Replies: 18
    Last Post: 04-03-2009, 08:20 PM
  2. Enforcing Machine Code Restrictions?
    By SMurf in forum Tech Board
    Replies: 21
    Last Post: 03-30-2009, 07:34 AM
  3. Obfuscated Code Contest
    By Stack Overflow in forum Contests Board
    Replies: 51
    Last Post: 01-21-2005, 04:17 PM
  4. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM
  5. Replies: 0
    Last Post: 02-21-2002, 06:05 PM