Re: [Geany-devel] Geany Newsletter Issue #5

2012-05-28 Thread Lex Trotman
Hi Thomas,

Humm, dunno why it didn't work when Matthew and I tried it before, but:

$ cat test.cpp
 #include 
 #include 


extern "C"
{
  PLUGIN_VERSION_CHECK(211)

  PLUGIN_SET_INFO("Test C++","Test C++", "etc", "etc");

  void plugin_init(GeanyData *){}
  void plugin_cleanup(void){}

}

class Test
{
public:
   Test() { std::cout << "Hello from Test" << std::endl; }
   ~Test() { std::cout << "Bye from Test" << std::endl; }
};

static Test test;

$ g++ -c test.cpp -fPIC `pkg-config --cflags ../lib/pkgconfig/geany.pc geany`
$ g++ test.o -o test.so -shared `pkg-config --libs
../lib/pkgconfig/geany.pc geany`
$ cp test.so ../lib/geany
$ geany -c ../config

does call the constructor/destructor for test.  Maybe we got the
mystery incantations wrong :)  It also works using clang++ to compile
test :)

Note, if the plugin isn't loaded the constructor is run when plugin
manager is opened and, if you havn't selected the plugin, the
destructor is run when plugin manager is closed.

When you select the plugin the destructor is run and then the
constructor is run again but this time the destructor is not run when
plugin manager is closed.

So it probably shouldn't do anything in the constructors/destructors
that is slow or that leaves a trace.

[...]
>
> FWIW, does anyone know why I needed to link libstdc++ explicitely in my
> testing?

As shown above Matthew is right, just use g++.

@Frank, sorry, wasn't meaning to blame you ;) just my failing .. ummm
... oh yeah, memory.

Cheers
Lex
___
Geany-devel mailing list
Geany-devel@uvena.de
https://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel


Re: [Geany-devel] Geany Newsletter Issue #5

2012-05-28 Thread Matthew Brush

On 12-05-28 02:24 PM, Thomas Martitz wrote:

Am 28.05.2012 13:27, schrieb Lex Trotman:


This doesn't actually call the C++ constructors/destructors in the way
they would be in normally be if the plugin had been statically linked.

This simply labels a C function to be called at dlopen time. It may
be used to do some initialisation, but you would have to manually call
each constructor, ... too error prone, Franks advice to create
everything dynamically is sound.



I meant to say that global/static constructors/destructors are in fact
called when a library is dlopened(), regardless of the language of
calling code.



I think that blurb in the newsletter was written before it was realized 
that the whole C++ runtime/magic was already present because of 
Scintilla. I wrote the paragraphs and IIRC Lex reviewed/revised it, but 
I can say I'm probably the least qualified to write about how to use C++ :)





$ gcc -o libtestcpp.so -shared -fPIC test.cpp -g -lstdc++
-Wl,--no-undefined


$ ./test
Hello from Test
hello from extern C function
Bye from Test



FWIW, does anyone know why I needed to link libstdc++ explicitely in my
testing?



Just guessing but maybe it's because of using the `gcc` command instead 
of `g++`? I only ever experienced needing to link to it explicitly with 
Geany/Scintilla. In my own pure C++ code it's never needed.


Cheers,
Matthew Brush

___
Geany-devel mailing list
Geany-devel@uvena.de
https://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel


Re: [Geany-devel] Geany Newsletter Issue #5

2012-05-28 Thread Thomas Martitz

Am 28.05.2012 13:27, schrieb Lex Trotman:


This doesn't actually call the C++ constructors/destructors in the way
they would be in normally be if the plugin had been statically linked.

This simply labels a C function to be called at dlopen time.  It may
be used to do some initialisation, but you would have to manually call
each constructor, ... too error prone, Franks advice to create
everything dynamically is sound.



I meant to say that global/static constructors/destructors are in fact 
called when a library is dlopened(), regardless of the language of 
calling code.


Anyway, I thought an example illustrates it better:


$ cat test.c
#include 
#include 
#include 
int main()
{
void* h = dlopen("/tmp/foo/libtestcpp.so", RTLD_NOW);
if (!h) { printf("no lib %s\n", dlerror()); exit(-1); }
void (*fn)(void) = dlsym(h, "hello");
if (!fn) exit(-2);
fn();
dlclose(h);
return 0;
}


$ gcc -o test test.c -ldl -g


$ cat test.cpp
#include 

namespace std {

class Test
{
public:
Test() { cout << "Hello from Test" << endl; }
~Test() { cout << "Bye from Test" << endl; }
};

static Test test;

}

extern "C" {

#include 

void hello(void)
{
printf("hello from extern C function\n");
}

}


$ gcc -o libtestcpp.so -shared -fPIC test.cpp -g -lstdc++ 
-Wl,--no-undefined



$ ./test
Hello from Test
hello from extern C function
Bye from Test



FWIW, does anyone know why I needed to link libstdc++ explicitely in my 
testing?


Best regards.
___
Geany-devel mailing list
Geany-devel@uvena.de
https://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel


Re: [Geany-devel] Geany Newsletter Issue #5

2012-05-28 Thread Frank Lanitz
Am 28.05.2012 13:27, schrieb Lex Trotman:
> On 28 May 2012 19:59, Thomas Martitz
>  wrote:
>> Am 28.05.2012 11:27, schrieb Frank Lanitz:
>>>
>>> It's important to note that the dynamic library loading mechanism
>>> that loads plugins is C functionality and does not know about C++
>>> constructors. This means that global and static objects in the
>>> plugin will *not* have their constructors called when the plugin is
>>> loaded. Use dynamically created objects as show in the above example.
>>>
>>
>> I'm not sure this is true. libdl should handle this (i.e. call functions
>> point to in the init and fini sections).
>>
>> |__attribute__ ((constructor)) and||__attribute__  ((destructor)) is
>> supported works with as well.
>>
> 
> This doesn't actually call the C++ constructors/destructors in the way
> they would be in normally be if the plugin had been statically linked.
> 
> This simply labels a C function to be called at dlopen time.  It may
> be used to do some initialisation, but you would have to manually call
> each constructor, ... too error prone, Franks advice to create
> everything dynamically is sound.

It's not mine, as I really don't have a clue about this section. Content
was introduced by a patch IIRC by Matthew and you ;)

Cheers,
Frank



signature.asc
Description: OpenPGP digital signature
___
Geany-devel mailing list
Geany-devel@uvena.de
https://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel


Re: [Geany-devel] Geany Newsletter Issue #5

2012-05-28 Thread Lex Trotman
On 28 May 2012 19:59, Thomas Martitz
 wrote:
> Am 28.05.2012 11:27, schrieb Frank Lanitz:
>>
>> It's important to note that the dynamic library loading mechanism
>> that loads plugins is C functionality and does not know about C++
>> constructors. This means that global and static objects in the
>> plugin will *not* have their constructors called when the plugin is
>> loaded. Use dynamically created objects as show in the above example.
>>
>
> I'm not sure this is true. libdl should handle this (i.e. call functions
> point to in the init and fini sections).
>
> |__attribute__ ((constructor)) and||__attribute__  ((destructor)) is
> supported works with as well.
>

This doesn't actually call the C++ constructors/destructors in the way
they would be in normally be if the plugin had been statically linked.

This simply labels a C function to be called at dlopen time.  It may
be used to do some initialisation, but you would have to manually call
each constructor, ... too error prone, Franks advice to create
everything dynamically is sound.

Cheers
Lex

> Best regards.
> |
>
> ___
> Geany-devel mailing list
> Geany-devel@uvena.de
> https://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel
___
Geany-devel mailing list
Geany-devel@uvena.de
https://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel


Re: [Geany-devel] Geany Newsletter Issue #5

2012-05-28 Thread Thomas Martitz

Am 28.05.2012 11:27, schrieb Frank Lanitz:

It's important to note that the dynamic library loading mechanism
that loads plugins is C functionality and does not know about C++
constructors. This means that global and static objects in the
plugin will *not* have their constructors called when the plugin is
loaded. Use dynamically created objects as show in the above example.



I'm not sure this is true. libdl should handle this (i.e. call functions 
point to in the init and fini sections).


|__attribute__ ((constructor)) and||__attribute__  ((destructor)) is supported 
works with as well.

Best regards.
|

___
Geany-devel mailing list
Geany-devel@uvena.de
https://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel


[Geany-devel] Geany Newsletter Issue #5

2012-05-28 Thread Frank Lanitz
Geany Newsletter #5
---

1   About Geany
2   New translations and updates
3   Wiki available
4   C++ plugins supported
5   Plugins
5.1 New Plugins
5.1.1   GeanyPyflakes
5.1.2   GeniusPaste
5.2 GeanyPG
6   Geany local
7   Geany Packages for Fedora
8   About this newsletter 


1 About Geany
=

Geany is a small and lightweight Integrated Development Environment.
It was developed to provide a small and fast IDE, which has only a
few dependencies from other packages. Another goal was to be as
independent as possible from a special Desktop Environment like KDE
or GNOME - Geany only requires the GTK2 runtime libraries.

More information about Geany can be found at
`geany.org `_.



2 New translations and updates
==

Since our last newsletter a number of translations has been updated
or newly added to Geany. New translations are:

* Arabian
* Indonesian
* Lithuanian
* Mongolian (back in 2011)

But also translations like German, Kazakh, Hungarian, Italian,
Traditional Chinese and Swedish translations have been updated
during the last roughly four month.


3 Wiki available


We set up a wiki for additional documentation and resources related 
to Geany at http://wiki.geany.org. Anyone can contribute to the wiki 
simply by registering and then logging in.

In the wiki you can find configuration snippets and tips, snippets for
various programming languages and many additional tags files to enhance
Geany's autocompletion features.

Everybody is welcome to add additional useful content to the wiki.


4 C++ plugins supported
===

Geany's public plugin API headers have been updated to support 
inclusion into C++ code. Most of the changes involve adding `extern 
"C" {...}` blocks around the public headers' code (by way of GLIB's 
`G_BEGIN_DECLS` and `G_END_DECLS` macros) to make them easier to 
include, so the C++ code doesn't need to do this.

You can now write plugins in C++ and they will be loadable by Geany 
at run-time. Of course using Geany's API will still involve using C 
in your code, but the rest of your plugin can use whatever C++ 
features you want. You can even use gtkmm [1] in your plugin if you 
want.

Any of the symbols Geany looks up at run-time must not have their 
names mangled by the compiler. To avoid this, put that code inside 
an `extern "C"` block.

Here's an example of Geany's Hello World plugin from the Plugin 
HowTo [2] ported to C++::

#include 

class HelloWorld
{
private:
gchar *hello_message;
GtkWidget *main_menu_item;

public:
HelloWorld(const gchar *message);
~HelloWorld();
void SayHelloWorld();
};

static HelloWorld *hello;

extern "C"
{
GeanyPlugin *geany_plugin;
GeanyData   *geany_data;
GeanyFunctions  *geany_functions;

PLUGIN_VERSION_CHECK(211)
PLUGIN_SET_INFO("HelloWorld C++",
"Just another tool to say hello 
world, this time in C++",
"1.0", "John Doe 
");

void plugin_init(GeanyData *data)
{
hello = new HelloWorld("Hello C++ World");
}

void plugin_cleanup(void)
{
delete hello;
}

static void on_menu_item_clicked(GtkMenuItem *item, gpointer 
user_data)
{
hello->SayHelloWorld();
}
}

HelloWorld::HelloWorld(const gchar *message)
{
hello_message = g_strdup(message);
main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
gtk_widget_show(main_menu_item);

gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu), 
main_menu_item);
g_signal_connect(main_menu_item, "activate", 
G_CALLBACK(on_menu_item_clicked), NULL);
}

HelloWorld::~HelloWorld()
{
g_free(hello_message);
gtk_widget_destroy(main_menu_item);
}

void HelloWorld::SayHelloWorld()
{
dialogs_show_msgbox(GTK_MESSAGE_INFO, "%s", hello_message);
}

It's important to note that the dynamic library loading mechanism 
that loads plugins is C functionality and does not know about C++ 
constructors. This means that global and static objects in the 
plugin will *not* have their constructors called when the plugin is 
loaded. Use dynamically created objects as show in the above example.

These changes will be available in the next Geany release but you 
can start using them