Implementing a GObject interface in C++ - c++

I try to implement a GType interface in C++ using Glibmm (part of Gtkmm). The object will be passed to an API in C. Unfortunately, the documentation for gtkmm does not cover many details of how it wraps the GObject system.
What I have so far:
class MonaCompletionProvider : public gtksourceview::SourceCompletionProvider, public Glib::Object
{
public:
MonaCompletionProvider();
virtual ~MonaCompletionProvider();
Glib::ustring get_name_vfunc() const;
// ... and some more
}
All method and constructor implementations are empty. The code is used like this:
Glib::RefPtr<MonaCompletionProvider> provider(new MonaCompletionProvider());
bool success = completion->add_provider(provider);
success will be false after executing this code and the following message appears in the command line:
(monagui:24831):
GtkSourceView-CRITICAL **:
gtk_source_completion_add_provider:
assertion
`GTK_IS_SOURCE_COMPLETION_PROVIDER
(provider)' failed
It seems that the underlying gobj() is not aware that it is supposed to implement this interface. If the class does not derive from Glib::Object, gobj() even returns null. I hope that I do not have to write a GObject implementing this interface in C manually.
So what is the correct way to do this? Thanks in advance.
PS: For those who are interested: SourceCompletionProvider

Finally, I found a solution.
Class definition (order of subclasses matters):
class MonaCompletionProvider : public Glib::Object, public gtksourceview::SourceCompletionProvider {
...
Constructor (again, order matters):
MonaCompletionProvider::MonaCompletionProvider() :
Glib::ObjectBase(typeid(MonaCompletionProvider)),
Glib::Object(),
gtksourceview::SourceCompletionProvider() {
...
Solution found by inspecting how it has been done in Guikachu.

Related

Override System class in Java and more precisely currentTimeMillis [duplicate]

Aside from recompiling rt.jar is there any way I can replace the currentTimeMillis() call with one of my own?
1# The right way to do it is use a Clock object and abstract time.
I know it but we'll be running code developed by an endless number of developers that have not implemented Clock or have made an implementation of their own.
2# Use a mock tool like JMockit to mock that class.
Even though that only works with Hotspot disabled -Xint and we have success using the code bellow it does not "persist" on external libraries. Meaning that you'd have to Mock it everywhere which, as the code is out of our control, is not feasible. All code under main() does return 0 milis (as from the example) but a new DateTime() will return the actual system millis.
#MockClass(realClass = System.class)
public class SystemMock extends MockUp<System> {
// returns 1970-01-01
#Mock public static long currentTimeMillis() { return 0; }
}
3# Re-declare System on start up by using -Xbootclasspath/p (edited)
While possible, and though you can create/alter methods, the one in question is declared as public static native long currentTimeMillis();. You cannot change it's declaration without digging into Sun's proprietary and native code which would make this an exercise of reverse engineering and hardly a stable approach.
All recent SUN JVM crash with the following error:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000, pid=4668, tid=5736
4# Use a custom ClassLoader (new test as suggested on the comments)
While trivial to replace the system CL using -Djava.system.class.loader JVM actually loads up the custom classLoader resorting to the default classLoader and System is not even pushed trough the custom CL.
public class SimpleClassLoader extends ClassLoader {
public SimpleClassLoader(ClassLoader classLoader) {
super(classLoader);
}
#Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
return super.loadClass(name);
}
}
We can see that java.lang.System is loaded from rt.jar using java -verbose:class
Line 15: [Loaded java.lang.System from C:\jdk1.7.0_25\jre\lib\rt.jar]
I'm running out of options.
Is there some approach I'm missing?
You could use an AspectJ compiler/weaver to compile/weave the problematic user code, replacing the calls to java.lang.System.currentTimeMillis() with your own code. The following aspect will just do that:
public aspect CurrentTimeInMillisMethodCallChanger {
long around():
call(public static native long java.lang.System.currentTimeMillis())
&& within(user.code.base.pckg.*) {
return 0; //provide your own implementation returning a long
}
}
I'm not 100% sure if I oversee something here, but you can create your own System class like this:
public static class System {
static PrintStream err = System.err;
static InputStream in = System.in;
static PrintStream out = System.out;
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
System.arraycopy(src, srcPos, dest, destPos, length);
}
// ... and so on with all methods (currently 26) except `currentTimeMillis()`
static long currentTimeMillis() {
return 4711L; // Your application specific clock value
}
}
than import your own System class in every java file. Reorganize imports in Eclipse should do the trick.
And than all java files should use your applicatikon specific System class.
As I said, not a nice solution because you will need to maintain your System class whenever Java changes the original one. Also you must make sure, that always your class is used.
As discussed in the comments, it is possible that option #3 in the original question has actually worked, successfully replacing the default System class.
If that is true, then application code which calls currentTimeMillis() will be calling the replacement, as expected.
Perhaps unexpectedly, core classes like java.util.Timer would also get the replacement!
If all of the above are true, then the root cause of the crash could be the successful replacement of the System class.
To test, you could instead replace System with a copy that is functionally identical to the original to see if the crashes disappear.
Unfortunately, if this answer turns out to be correct, it would seem that we have a new question. :) It might go like this:
"How do you provide an altered System.currentTimeMillis() to application classes, but leave the default implementation in place for core classes?"
i've tried using javassist to remove the native currentTimeMills, add a pure java one and load it using bootclasspath/p, but i got the same exception access violation as you did. i believe that's probably because of the native method registerNatives that's called in the static block but it's really too much to disassemble the native library.
so, instead of changing the System.currentTimeMills, how about changing the user code? if the user code already compiled (you don't have source code), we can use tools like findbugs to identify the use of currentTimeMillis and reject the code (maybe we can even replace the call to currentTimeMills with your own implementation).

Calling a C++ dll method from Java using JNA and avoiding Method Name Mangling

I have been going through links on StackOverflow on how to resolve the Method name mangling but did not find any solution with a real time example.
Scenario-A C++ Ex.dll file is provided by client. I need to access the Ex.dll and call the methods in the same through Java.
Restrictions- Cannot modify the Ex.dll, i can only access the same.
Issue Faced- Getting the below exception when i access the Ex.dll through JNA
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'getCPUSpeed': The specified procedure could not be found.
at com.sun.jna.Function.<init>(Function.java:134)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:336)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:316)
at com.sun.jna.Library$Handler.invoke(Library.java:203)
at $Proxy0.getCPUSpeed(Unknown Source)
at cpp.java.JnaTest.main(JnaTest.java:16)
Googled a lot and found that its due to method name Mangling, but again could not find any good sample code with the solution.
This is code i used-
import com.sun.jna.Native;
class JnaTest
{
public static void main(String args[])
{
try
{
JnaInterface jInterface = (JnaInterface) Native.loadLibrary("Ex", JnaInterface.class);
System.out.println("Calling C++ DLL method");
System.out.println("========================");
System.out.println("getCPUSpeed() -- "+jInterface.getCPUSpeed());
} catch (Exception e) {
e.printStackTrace();
}
}
}
package cpp.java;
import com.sun.jna.Library;
public interface JnaInterface extends Library{
public int getCPUSpeed();
}
Update 1: **************************************
Below mentioned is the actual functions i get when i browse the DBMM.dll through dependency walker-
DBMM DLL functions-
??0cDbmmInterfaceCache##QAE#ABV0##Z
??0cDbmmInterfaceCache##QAE#XZ
??0cDbmmInterfaceControl##QAE#ABV0##Z
??0cDbmmInterfaceControl##QAE#XZ
??0cDbmmInterfaceEcon##QAE#ABV0##Z
??0cDbmmInterfaceEcon##QAE#XZ
??0cDbmmInterfaceKnob##QAE#XZ
??0cDbmmInterfaceOutput##QAE#ABV0##Z
??0cDbmmInterfaceOutput##QAE#H#Z
??0cDbmmInterfacePoolLoan##QAE#ABV0##Z
??0cDbmmInterfacePoolLoan##QAE#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z
??0cDbmmMacroEcon##QAE#ABV0##Z
??0cDbmmMacroEcon##QAE#ABVcDbmmInterfaceEcon##_N#Z
??0cDbmmMtgBasisConstSpreadModel##IAE#XZ
??0cDbmmMtgBasisConstSpreadModel##QAE#ABV0##Z
??0cDbmmMtgBasisConstSpreadModel##QAE#PBD#Z
??0cDbmmMtgBasisModel##QAE#ABV0##Z
??0cDbmmMtgBasisModel##QAE#XZ
??0cScaleFieldsSubSum##QAE#NN#Z
??1cDbmmInterfaceCache##QAE#XZ
??1cDbmmInterfaceControl##QAE#XZ
??1cDbmmInterfaceEcon##QAE#XZ
??1cDbmmInterfaceKnob##QAE#XZ
??1cDbmmInterfaceOutput##QAE#XZ
??1cDbmmInterfacePoolLoan##QAE#XZ
??1cDbmmMacroEcon##QAE#XZ
??1cDbmmMtgBasisConstSpreadModel##UAE#XZ
??1cDbmmMtgBasisModel##UAE#XZ
??1cScaleFieldsSubSum##QAE#XZ
??4cDbmmInterface##QAEAAV0#ABV0##Z
??4cDbmmInterfaceCache##QAEAAV0#ABV0##Z
??4cDbmmInterfaceControl##QAEAAV0#ABV0##Z
??4cDbmmInterfaceEcon##QAEAAV0#ABV0##Z
??4cDbmmInterfaceKnob##QAEAAV0#ABV0##Z
??4cDbmmInterfaceOutput##QAEAAV0#ABV0##Z
??4cDbmmInterfacePoolLoan##QAEAAV0#ABV0##Z
??4cDbmmMacroEcon##QAEAAV0#ABV0##Z
??4cDbmmMtgBasisConstSpreadModel##QAEAAV0#ABV0##Z
??4cDbmmMtgBasisModel##QAEAAV0#ABV0##Z
??4cScaleFieldsSubSum##QAEAAV0#ABV0##Z
??_7cDbmmMtgBasisConstSpreadModel##6B#
??_7cDbmmMtgBasisModel##6B#
??_FcDbmmInterfaceOutput##QAEXXZ
??_FcDbmmInterfacePoolLoan##QAEXXZ
??_FcScaleFieldsSubSum##QAEXXZ
?Add#cScaleFieldsSubSum##QAEXNN#Z
?InitSubsum#cScaleFieldsSubSum##QAEXNN#Z
?ReInit#cDbmmMacroEcon##QAEX_N#Z
Not sure how can i call these functions through Java.
Appreciate if somebody could provide me a solution from Java end, with a sample code please :)
Your function is decorated with JNI and stdcall conventions; it is not C++-mangled.
It looks like the library is a JNI library, given the Java_sysInfo_ prefix. If that is the case, you need only declare the equivalent Java-side, e.g.
// default package
public class sysInfo {
static { System.loadLibrary("Ex"); }
public static native int getCPUSpeed();
}
I think you'll probably find that this mapping is the correct one and that you don't need JNA.
EDIT
Given a C++ class with an arbitrary ctor input argument and method getCount():
extern "C" int getCountForName(const char* name) {
MyCPPClass mycpp(name);
return mycpp.getCount();
}
Compile that into a shared library, and load via JNA.
If your building the DLL through Visual studio, you should be able to build it as a release instead of debug to fix the function names if you are not already doing this.

c# programmer tries for events in c++

Hi all: I'm an experienced c# programmer trying to do some work in c++, and I'm not sure about the right way to do this:
I am authoring a class that needs to notify a consuming class that something has happened.
If I were writing this in c#, I would define an event on my class.
No events in c++, so I am trying to figure out what is the correct way to do this. I have thought about callback functions, but how do I handle a case where I want to execute a member function (not a static function).
More specifically, what I really need to do is to handle the event, but have access to member state within the object instance that is handling the event.
I have been looking at std::tr1:function, but I am having trouble getting it to work.
I don't suppose that anyone would want to translate the following example c# example into an example of the correct/best practice c++ (I need ANSI c++)?
(please bear in mind that I have almost no c++ experience -- don't assume that I know any long-established c++ conventions -- I don't ;);
A simple c# console app (works on my machine):
using System;
namespace ConsoleApplication1
{
public class EventSource
{
public event EventHandler<EchoEventArgs> EchoEvent;
public void RaiseEvent(int echoId)
{
var echoEvent = this.EchoEvent;
if (echoEvent != null)
echoEvent(this, new EchoEventArgs() {EchoId = echoId});
}
}
public class EchoEventArgs : EventArgs
{
public int EchoId { get; set; }
}
public class EventConsumer
{
public int Id { get; set; }
public EventConsumer(EventSource source)
{
source.EchoEvent += OnEcho;
}
private void OnEcho(object sender, EchoEventArgs args)
{
// handle the echo, and use this.Id to prove that the correct instance data is present.
Console.WriteLine("Echo! My Id: {0} Echo Id: {1}", this.Id, args.EchoId);
}
}
internal class Program
{
private static void Main(string[] args)
{
var source = new EventSource();
var consumer1 = new EventConsumer(source) { Id = 1 };
var consumer2 = new EventConsumer(source) { Id = 2 };
source.RaiseEvent(1);
Console.ReadLine();
}
}
}
The basic idea is to take function objects, e.g., something like std::function<Signature> as the callbacks. These aren't function pointers but can be called. The standard C++ library (for C++ 2011) contains a number of class and functions, e.g., std::mem_fn() and std::bind() which allow using functions, including member functions, to be used as function objects.
The part what is missing is something supporting multiple events be registered: std::function<Signature> represents one function. However, it is easy to put them, e.g., into a std::vector<std::function<Signature>>. What becomes more interesting (and requires variadic templates to be done easily) is creating an event class which encapsulates the abstraction of multiple events begin registered, potentially unregistered, and called.
C++ has a concept of functor: a callable object. You need to read about them.
Think about an object that has overwritten operator(). You pass an instance of such an object. After that you can call it like a regular function. And it can maintain a state.
There's also Signals2 library in Boost, which provides an API very close to real C# events, at least in idiomatic sense.
Qt has something that might help you called Signals and Slots: http://qt-project.org/doc/qt-4.8/signalsandslots.html
It lets you specify what the signals (the events that you want to listen to) and the slots (the receiving side) an object has, and then you can connect them. More than one object can listen to a signal like you mention you needed.
Qt is a large app framework, so I'm not sure how to use only the signals & slots part of it. But if you're building an entire GUI application the rest of the Qt might benefit you too (a lot of the ui event stuff is based on signals and slots).

Should I write components in Delphi instead of C++ Builder? How do I add events to a component?

I use C++ Builder (XE2) and I would need to develop some VCL components that would also be used in Delphi. As I understand C++ Builder supports Delphi code and Delphi components but not the other way around? If so, it would be better to start writing it in Delphi so that I don't do a double job?
Second part of my question is more technical; I know how to add a property in a VCL component but don't know how to add events. Could someone give me an example please (no matter Delphi or C++ Builder).
Thanks.
As I understand C++ Builder supports Delphi code and Delphi components but not the other way around?
On source level - yes.
But if you choose to distribute your library sourceless - BPL+DCP+DCU - then it would not matter, except for maybe some small incompatibilities, like Delphi lacking [] operator and C++ lacking virtual overloaded constructors.
Turns out this estimation was wrong. Read Remy's comment below
Most close to you example ov events is the VCL itself, sources are usually shipped with Delphi. If you have Delphi Starter/Trial without VCL sources - then get any opensource VCL library or component. Such as JediVCL or basically almost ANY VCL component with sources. For example any "FWS" (Free with sources) component 99% uses events.
Most basic and widely used event notifications type - such as TButton.OnClick, TForm.OnCreate and a lot of - is TNotifyEvent
Open Delphi Help for that type. Scroll to "See also" and see two links there.
Procedural types are like int (*f)(void) in C.
Events creating manual
Such as:
(borrowed code from about.delphi.com)
type
TState = (stStarted, stStopped);
TStateChangeEvent = procedure
(Sender : TObject; State : TState) of object;
TThirdComponent = class(TSecondComponent) // or whatever
private
{ Private declarations }
FState : TState;
FOnStart,
FOnStop : TNotifyEvent;
FOnStateChange : TStateChangeEvent;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
procedure Start; override;
procedure Stop; override;
property State : TState
read FState;
published
{ Published declarations }
property OnStart : TNotifyEvent
read FOnStart
write FOnStart;
property OnStateChange : TStateChangeEvent
read FOnStateChange
write FOnStateChange;
property OnStop : TNotifyEvent
read FOnStop
write FOnStop;
end
Then you can do
procedure TThirdComponent.Start;
begin
inherited;
FState := stStarted;
if Assigned(OnStart) then OnStart(Self);
if Assigned(OnStateChange) then
OnStateChange(Self, State);
end;

Firebreath how to know if my method is called without debugging

I am using Objective-C++ in my firebreath project. The problem is that I am using Xcode 4 and I can not find the way to debug my project. So I have thought about if my method is been called from the web page.
Here is my source code:
In my OpenOnDesktopPluginAPI.h class:
class OpenOnDesktopPluginAPI : public FB::JSAPIAuto
{
public:
OpenOnDesktopPluginAPI(const OpenOnDesktopPluginPtr& plugin, const FB::BrowserHostPtr& host);
virtual ~OpenOnDesktopPluginAPI();
OpenOnDesktopPluginPtr getPlugin();
...
//This is my method
void runNotification();
...
};
In my OpenOnDesktopPluginAPI.mm class:
OpenOnDesktopPluginAPI::OpenOnDesktopPluginAPI(const OpenOnDesktopPluginPtr& plugin, const FB::BrowserHostPtr& host) : m_plugin(plugin), m_host(host)
{
...
//Register my method
registerMethod("runNotification", make_method(this, &OpenOnDesktopPluginAPI::runNotification));
...
}
//DistributedNotification class is my objective-c class with the implementation for post a distributed notification.
void OpenOnDesktopPluginAPI::runNotification()
{
DistributedNotification * notificationClass = [[DistributedNotification alloc] init];
[notificationClass postNotification];
[notificationClass release];
}
In my FBControl.html:
...
function myFunction()
{
plugin().runNotification();
}
...
My new method
...
I put my DistributedNotification.mm class in the
Build Phases -> "Compile Sources"
for my plugin target.
But I donĀ“t know if my runNotification method is called, because when (In my web page) I click on My new method link, nothing happens.
I'll repeat what I said on the forum when you ask; perhaps you haven't seen that answer yet:
First of all, you can debug with Xcode4, at least on some browsers; the trick is figuring out which process to connect to.
Secondly, you can always use NSLog to log things to the console. Thirdly, you could use log4cplus (see http://www.firebreath.org/display/documentation/Logging).
Finally, you haven't specified what browser you're testing on, nor have you indicated what happens. It looks reasonable, but aparently doesn't work? What doesn't work? What does it do?
It's nearly impossible to give you any useful advice without detailed information about what you are encountering.