Is Objective-c runtime means an extra layer than direct c/c++ programs? - objective-c

I've read that, the objective-c programs need objective-c runtime to run.
AFAIK, both C/C++ programs don't require any runtime environments to run. as the generated binary code is being executed directly by the underlying OS.
So this means that Objective-c programs require a redundant layer to run, correct? and If so, is this layer seems like Java VM and .net runtime or seems like Qt runtime (in flavor of some additional libraries)?
EDIT:
After some read, I found that, the objc compiler generates some more information in the generated compiled code that is responsible of many things such as method passing (objc_sendMsg(), introspection and others)
Thanks.

The compiled code is native but you need an additional library (the runtime) which does all the object and message handling (lookup, invocation etc.). There is no virtual machine involved. So it is more like QT than Java runtime.
[Update]
Since the C++ message binding behaviour is not obvious to programmers of more dynamic OO languages (e.g.: Objective-C or Smalltalk) - like me - I wrote a small C++ test app which demonstrates the effect of the virtual keyword on the choice of the method to call.
#include <iostream>
class Test1 {
public:
Test1();
void test1();
void test2();
};
class Test2 : Test1 {
public:
Test2();
void test1();
void test2();
};
Test1::Test1() {}
void Test1::test1() { std::cout << "T1:t1" << std::endl; }
void Test1::test2() { std::cout << "T1:t2" << std::endl; }
Test2::Test2() {}
void Test2::test1() { std::cout << "T2:t1" << std::endl; }
void Test2::test2() { std::cout << "T2:t2" << std::endl; }
int main(int argc, char **argv)
{
Test1 *t11 = new Test1();
Test1 *t12 = (Test1 *)(new Test2());
Test2 *t2 = new Test2();
t11->test1();
t11->test2();
t12->test1();
t12->test2();
t2->test1();
t2->test2();
return 0;
}
An Objective-C programmer would expect a output of
T1:t1
T1:t2
T2:t1
T2:t2
T2:t1
T2:t2
since t12 is actually a Test2 which was casted to Test1.
The actual output is
T1:t1
T1:t2
T1:t1
T2:t2
T2:t1
T2:t2
because C++ (by default, i.e. without virtual) statically binds the call to test1 based on the type it knows at compile time which is Test1 (due to the cast).

Related

Why singleton in headers not work for Windows/MinGW?

Here are my codes for PoC:
a.h: which implements a singleton method to create A instance
#pragma once
class A
{
public:
int a;
static A& Instance() {
static A a;
return a;
}
};
b.h: which declares a function will try to create an A instance inside, and output the address of it.
#pragma once
void test_b();
b.cc: The implementation of test_b
#include "b.h"
#include <iostream>
#include "a.h"
void test_b() {
auto &a = A::Instance();
std::cout << "a address in test_b: " << (void *)(&a) << std::endl;
}
and c.cc: test_c which do the same things as test_b, and call test_b and test_c in main to check if the singleton is working.
#include <iostream>
#include "a.h"
#include "b.h"
void test_c() {
auto &a = A::Instance();
std::cout << "a address in test_c: " << (void *)(&a) << std::endl;
}
int main() {
test_b();
test_c();
return 0;
}
I using the b.cc to build a shared library libb.so in windows(libb.dll), and using c.cc to create the test_app which links with the shared library.
I've tested the above codes in Linux and Windows(MinGW), but I've got different results.
Under linux the output is like:
a address in test_b: 0x601174
a address in test_c: 0x601174
And under MinGW the output is like:
a address in test_b: 0x7ff87df93070
a address in test_c: 0x7ff731ef30b0
The makefile I used for the build.
Makefile:
test_app: c.cc libb.so
g++ -o $# $^ -lb
libb.so: a.h b.cc
g++ -o $# -fPIC -shared b.cc
Makefile.mingw
test_app.exe: c.cc libb.dll
g++ -o $# $^ -lb -L.
libb.dll: a.h b.cc
g++ -o $# -fPIC -shared b.cc
I know implementing Singleton in the header file is not a good practice, but if anyone could help to explain why?
As far as the language is concerned, the lvalue returned by A::Instance must always refer to the same object within the execution of the program. If a language implementation deviates from that, then it doesn't conform to the standard.
why?
You are using shared libraries which are an extension of the language. As you've witnessed, using this language extension causes the language implementation to deviate from the guarantees given by the standard.
You can work around the issue by defining the instance getter as a non-inline function in a single translation unit, rather than as an inline function. Another way is to use language implementation specific function attributes to control the shared library behaviour as per the documentation of the language implementation (dllexport, dllimport in MSVC).
Sidenote: Singleton pattern requires that the class is encapsulated such that no instances besides the static one can be created. The example is just a static local object and technically not a singleton since the constructor isn't encapsulated.

State machines, encapsulation and OOP design

I'm implementing a FSM using Boost's MSM library.
In the FSM, I have transition tables which describe Events, Source states, Target states, Actions and Guards.
It's my first time using a higher-level design of a state machine. In the past, I've just used switch statments and executed code. However, this one is going to be big and I wanted to keep everything organized properly so it doesn't turn into a mess.
I have an object that represents the state machine (it's a boost::msm::back::state_machine<MyStateMachine> where MyStateMachine is my implemenmtation which inherits from boost::msm::front::state_machine_def ).
The trick is that my business logic will be done in the Actions. I don't think that's uncommon for a FSM. Boost's examples seems to suggest that these Actions should be implemented as methods in the state machine itself, but I'm thinking that this just might make the one class too massive. I feel it makes sense to separate the work from the state machine.
Which makes more sense to keep a readable, maintainable, and extendable design?
Do the business logic in methods in the FSM class (I'm worried that this mixes state management with work too closely).
Do the business logic in the parent which instantiates the FSM. The FSM will need a pointer to the parent, and the parent will need to implement an interface that the FSM understands (that, or the FSM implementation will need to #include the declaration of the parent).
Do the business logic in a new class which is instantiated and owned by the FSM.
Do the business logic in a new class which is instantiated and owned by the parent, but passed as a reference (or pointer) to the FSM.
Something else.
It depends on your situation but I have one approach I usually use.
Maybe it is a variation of the 2 or 5.
Let's say your_app has your business logic. And it needs to behave as state-machine. I think that it is one of the typical use-case of the state-machine.
In this case, the state-machine can be placed as the nested class of the your_app. your_app has the member variable sm_, state-machine instance.
The definition of the state-machine is sm_def. It has the reference of the your_app.
When someone that is outside of the your_app want to process an event, call your_app::process_event(). If you don't want to provide direct event process interface, you can wrap it as your_app::handle_some(). If you do so, your_app::process_event() should be private.
Here is example implementation:
#include <iostream>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>
namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace mpl = boost::mpl;
// application domain
class your_app {
public:
your_app() :sm_(boost::ref(*this)) {
sm_.start(); // start state machine
}
// public interface for event processing
// Event definitions
struct Event1 {
int param;
};
template <typename Event>
void process_event(Event const& ev) {
sm_.process_event(ev);
}
void handle_some(int param) {
process_event(Event1 {param});
}
private:
// internal business logic triggered from the state machine
void do_some_business(int param) {
std::cout << "do_some_business " << param << std::endl;
}
// state machine definiition
struct sm_def:msmf::state_machine_def<sm_def> {
sm_def(your_app& ya):ya_(ya) {}
// States
struct State1:msmf::state<> {
template <class Event,class Fsm>
void on_entry(Event const&, Fsm&) {
std::cout << "State1::on_entry()" << std::endl;
}
template <class Event,class Fsm>
void on_exit(Event const&, Fsm&) {
std::cout << "State1::on_exit()" << std::endl;
}
};
struct State2:msmf::state<> {
template <class Event,class Fsm>
void on_entry(Event const&, Fsm&) {
std::cout << "State2::on_entry()" << std::endl;
}
template <class Event,class Fsm>
void on_exit(Event const&, Fsm&) {
std::cout << "State2::on_exit()" << std::endl;
}
};
// Set initial state
typedef State1 initial_state;
// Actions
struct Action {
template <class Event, class Fsm, class SourceState, class TargetState>
void operator()(Event const& e, Fsm& f, SourceState&, TargetState&) const {
// get your_app via Fsm.
f.ya_.do_some_business(e.param);
}
};
// Transition table
struct transition_table:mpl::vector<
// Start Event Next Action Guard
msmf::Row < State1, Event1, State2, Action, msmf::none >,
msmf::Row < State2, Event1, State1, Action, msmf::none >
> {};
your_app& ya_;
};
friend class sm; // give the friend access to the sm
typedef msm::back::state_machine<sm_def> sm;
sm sm_;
};
int main() {
your_app ya;
ya.process_event(your_app::Event1{42});
ya.handle_some(44);
}
And running demo: https://wandbox.org/permlink/PQGSGr0bnJHgaMpD

MSVC C++11: non-standard constructor inheritance

In my Windows Native C++ library I've sometimes overdone it in terms of constructors without providing actual methods with same functionality (5-10 extra constructors). This makes basic extending a C++ class really hard as there's no proper constructor inheritance (without redeclaring them and forwarding calls).
I use MSVC. (Yes, smile all you want!) Question is: Is there a way to inherit constructors except the default constructor/copy-constructor using using? Because, if someone decided to extend a class where I abuse constructors (w/o adding new properties and with single inheritance), it's a nightmare.
(example code)
class parent {
public:
parent(){
std::cout << __FUNCTION__ << ':' << __LINE__ << std::endl;
}
// a non-standard constructor
parent(const std::nullptr_t&):parent(){
std::cout << __FUNCTION__ << ':' << __LINE__ << std::endl;
}
};
// adds nothing to parent but helper methods
// and maybe self-reliant properties with their own constructors
// so no constructor is required to initialize child class properties
class child: public parent {
public:
// using parent::parent; // of no real use
child(){
std::cout << __FUNCTION__ << ':' << __LINE__ << std::endl;
}
// need to forward call
child(const std::nullptr_t&):parent(nullptr){
std::cout << __FUNCTION__ << ':' << __LINE__ << std::endl;
}
};
This multiple-constructor inheritance nightmare occurs especially when I build a my base CRTP class and need to extend it to build my default class and then allow others to extend and build their own variants while maintaining chainable method functionality (parent to child) in order.
In MSVC anyways, using parent::parent does not inherit the parent(const std::nullptr_t&). Is it supposed to according to the C++11 standard or not? Should I expect such functionality in VC13? This will greatly impact my choice in style for this public rewrite.
I also wonder why, for C++11, they did not figure out that when I'm extending a single class and not adding new properties, it should inherit the parent's default behavior (constructors, assignment operators, etc.). It just makes sense... and the compiler could figure it out.
According to the VS2013 Roadmap from Herb Sutter's talk at //build, inheriting constructors are not coming to VC++ in the near future:
They are "planned."
Delegating / inheriting ctors:
parent(const std::nullptr_t&):parent() { /* ... */
This is a delegating ctor [class.base.init]/6, whereas
using parent::parent;
inherits ctors from parent (all but copy/move ctors), according to the C++11 Standard [class.inhctor]
Question is: Is there a way to inherit constructors except the default copy-constructor using using?
Yes, for C++11. MSVC doesn't support that yet, and according to this MS site, VS2013 will support delegating ctors (but doesn't mention inheriting ctors).
I also wonder why, for C++11, they did not figure out that when I'm extending a single class and not adding new properties, it should inherit the parent's default behavior
No assumptions. Your derived class might need to be initialized differently. Inheriting ctors solve the problem with one line.
Is anything like version 3 even remotely possible?
I'm aware of that question, but I'm not that up-to-date with the latest drafts and proposals to be able to answer that for C++1y. For C++11, AFAIK, it's not possible - you can use macros to make it shorter (but not necessarily nicer):
#define EMPTY
#define DEF_MYCLASS_MEM(RET) template <typename tnChar> RET MyClass<tnChar>::
#define MYCLASS_TYPE typename MyClass<tnChar>
DEF_MYCLASS_MEM(EMPTY) MyClass() {}
DEF_MYCLASS_MEM(MYCLASS_TYPE::tString) Method1(const tString& aParam) const {
return aParam;
}

Dumpbin shows strange method name (generating exporting function in MS Visual C++)

I have created new Win32 project in my VS and have selected Dynamic Library ( *.dll ) for this aim.
I have defined some exporting function in the main file:
__declspec(dllexport)
int TestCall(void)
{
int value = 4 / 2;
std::cout << typeid(value).name() << std::endl;
return value;
}
__declspec(dllexport)
void SwapMe(int *first, int *second)
{
int tmp = *first;
*first = *second;
*second = tmp;
}
When I've looked at the dumpin /exports, I've got:
ordinal hint RVA name
1 0 00001010 ?SwapMe##YAXPEAH0#Z
2 1 00001270 ?TestCall##YAHXZ
I'm calling in the C# version like this:
[DllImport(#"lib1.dll", EntryPoint = "?TestCall##YAHXZ",
CallingConvention = CallingConvention.Cdecl)]
static extern int TestCall();
It's not the correct form of using exported methods. Where did I fail with generating such names for exporting-methods in the C++ dll project?
This is normal, the C++ compiler applies name decoration to functions. The C++ language supports function overloading, much like C# does. So you could write a Foo(int) and a Foo(double) function. Clearly they cannot both be exported as a function named "Foo", the client code wouldn't know which one to call. So the extra characters encode the name so that it is unique for the overload.
You can turn that off by declaring the function extern "C", the C language doesn't support overloading so doesn't require the same kind of decoration.
But it is actually better if you don't. Because it is also an excellent way to catch mistakes. Like changing the function declaration in your C++ code but forgetting to modify the pinvoke declaration in your C# code. You will now get an easy to diagnose "Entrypoint not found" exception instead of a non-descriptive and very hard to diagnose AccessViolationException. Which doesn't necessarily have to be raised in the C++ code, the stack imbalance can also crash your C# code. Looking up the decorated name is a bit painful however, improve that by asking the linker to create a map file (/MAP option).
use extern "C" to specify the linkage to avoid the name mangling:
extern "C" __declspec(dllexport) int TestCall(void);
extern "C" __declspec(dllexport) void SwapMe(int *first, int *second);

C++/CLI managed wrapper around C static library

Help!
I'm totally exhausted/frustrated with what seems to be a reasonably easy task. I’m not sure what I'm doing wrong; let alone if I'm doing it correct. I'm "required" to use an existing library (a C static library – over 100,000 lines of straight C code) in developing a WPF application (VS 2010, C# 4.0). Oh, and I can't touch the existing C code - use it as is!
I've read so many postings (advanced topics, how-to, etc), yet I'm so new to C++/CLI that it's just not making sense. From what I've read the best approach is to wrap the C static library as follows:
Unmanaged C static library <---> C++/CLI managed wrapper DLL <--->
managed WPF application
This is the stripped down C header file:
/* Call this function to execute a command. */
int issue_command(int command, long param1, long param2);
/* Completion call back function; you must supply a definition. */
extern int command_completed(int command, long param1, long param2);
struct struct_command_str
{
char command_str[10];
char param1_st[2];
char param2_st[2];
char success;
};
/* You must supply definitions to the following extern items. */
extern int command_status;
extern struct struct_command_str command_str;
The problem(s):
What I can’t seem to do correctly is provide a C++/CLI implementation for the call back functions, and the two extern items (command_status and struct command_str).
Can someone provide a sample C++/CLI implementation for the above missing call back functions and externs?
Thanks in advance for your assistance.
in your C++/CLI managed wrapper project, add 2 files :
a .c file :
extern void doSomething();
int command_status = 0;
struct_command_str command_str = { "command1", "p1", "p2", 't' };
int command_completed(int command, long param1, long param2) {
...
command_status = 1;
...
doSomething();
...
command_status = 2;
...
return 3;
}
a cpp file
void doSomethingManagedWrapper() {
...
call managed code
...
}
void doSomething() {
doSomethingManagedWrapper();
}
when you implement these in your c++/cli module, use the same signature shown in the c header file,but prefixed with extern "C".
also put an extern "C" block around the #include of the C header file.