私はC++フレームワーク用のラッパーを作成したいと思います。このフレームワークはちょっとバギーで、C++ではうまくいきません。だから私は彼らのフレームワークの外側から(良い古いCファイルを介して)彼らのメソッドを呼び出すことができるようにしたいと思います。これは、C++の代わりにCで使用するために必要なフレームワークメソッドをカプセル化するラッパーの必要性のように思えます。Cプログラム内でC++共有ライブラリを呼び出す...管理する方法は?
....ここでは、私はすでにやったことでこれまでのところは良い:(このフォルダを含める私、超音波法は、フレームワークの外から呼ばれるべきである)
インタフェース aldebaran.h :
#ifndef _ALDEBARAN_H
#define _ALDEBARAN_H
#ifdef __cplusplus
extern "C" {
#endif
void subscribe_ultrasound();
void unsubscribe_ultrasound();
float read_ultrasound();
#ifdef __cplusplus
}
#endif
#endif
今ラッパー:
のcppファイルaldebaran.cpp:
aldebaran.cppため#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "aldebaran.h"
#include "alproxy.h"
#include "../../include/aldebaran.h"
/*
* Ultrasound defines
*/
#define ULTRASOUND_RESERVATION_MAGIC "magic_foobar"
#define ULTRASOUND_POLL_TIME 250
#define ULTRASOUND_READ_ATTEMPTS 50
#define ULTRASOUND_SLEEP_TIME 20
using namespace std;
using namespace AL;
/*
* Framework proxies
*/
ALPtr<ALProxy> al_tts;
ALPtr<ALProxy> al_led;
ALPtr<ALProxy> al_motion;
ALPtr<ALProxy> al_mem;
ALPtr<ALProxy> al_us;
ALPtr<ALProxy> al_cam;
ALPtr<ALProxy> al_dcm;
/*
* Constructor
*/
Aldebaran::Aldebaran(ALPtr<ALBroker> pBroker, std::string pName): ALModule(pBroker, pName)
{
try {
al_tts = this->getParentBroker()->getProxy("ALTextToSpeech");
al_led = this->getParentBroker()->getProxy("ALLeds");
al_motion = this->getParentBroker()->getProxy("ALMotion");
al_mem = this->getParentBroker()->getProxy("ALMemory");
al_us = this->getParentBroker()->getProxy("ALUltraSound");
al_cam = this->getParentBroker()->getProxy("NaoCam");
al_dcm = this->getParentBroker()->getProxy("DCM");
}catch(ALError& err){
std::cout << "XXX: ERROR: " << err.toString() << std::endl;
return 1;
}
printf("XXX: module aldebaran initiated\n");
fflush(0);
}
/*
* Destructor
*/
Aldebaran::~Aldebaran()
{
printf("XXX: module aldebaran destructed\n");
fflush(0);
}
/*
* Subscribe to ultrasound module
*/
void subscribe_ultrasound()
{
ALValue param;
param.arrayPush(ULTRASOUND_POLL_TIME);
al_us->callVoid("subscribe", string(ULTRASOUND_RESERVATION_MAGIC), param);
printf("XXX: ultrasound subscribed: %s\n", ULTRASOUND_RESERVATION_MAGIC);
fflush(0);
}
/*
* Unsubscribe to ultrasound module
*/
void unsubscribe_ultrasound()
{
al_us->callVoid("unsubscribe", string(ULTRASOUND_RESERVATION_MAGIC));
printf("XXX: ultrasound unsubscribed: %s\n", ULTRASOUND_RESERVATION_MAGIC);
fflush(0);
}
/*
* Read from ultrasound module
*/
float read_ultrasound()
{
int i;
float val1, val2;
float val_sum;
ALValue distance;
val_sum = .0f;
for(i = 0; i < ULTRASOUND_READ_ATTEMPTS; ++i){
SleepMs(ULTRASOUND_SLEEP_TIME);
distance = al_mem->call<ALValue>("getData", string("extractors/alultrasound/distances"));
sscanf(distance.toString(AL::VerbosityMini).c_str(),"[%f, %f, \"object\"]", &val1, &val2);
val_sum += val1;
}
return val_sum/(1.f * ULTRASOUND_READ_ATTEMPTS);
}
定義ファイル:
#ifndef ALDEBARAN_API_H
#define ALDEBARAN_API_H
#include <string>
#include "al_starter.h"
#include "alptr.h"
using namespace AL;
class Aldebaran : public AL::ALModule
{
public:
Aldebaran(ALPtr<ALBroker> pBroker, std::string pName);
virtual ~Aldebaran();
std::string version(){ return ALTOOLS_VERSION(ALDEBARAN); };
bool innerTest(){ return true; };
};
#endif
だからこれは私のラッパーの簡単な例である必要があり、それがlibaldebaran.soする罰金コンパイルします。
Cで、今私のテストプログラム:
...今、私はこのような単純なCファイルからメソッドaldebaran.hインターフェースを呼び出すしたいと思います:
#include <stdio.h>
/*
* Begin your includes here...
*/
#include "../include/aldebaran.h"
/*
* End your includes here...
*/
#define TEST_OKAY 1
#define TEST_FAILED 0
#define TEST_NAME "test_libaldebaran"
unsigned int count_all = 0;
unsigned int count_ok = 0;
const char *__test_print(int x)
{
count_all++;
if(x == 1){
count_ok++;
return "ok";
}
return "failed";
}
/*
* Begin tests here...
*/
int test_subscribe_ultrasound()
{
subscribe_ultrasound();
return TEST_OKAY;
}
int test_unsubscribe_ultrasound()
{
unsubscribe_ultrasound();
return TEST_OKAY;
}
int test_read_ultrasound()
{
float i;
i = read_ultrasound();
return (i > .0f ? TEST_OKAY : TEST_FAILED);
}
/*
* Execute tests here...
*/
int main(int argc, char **argv)
{
printf("running test: %s\n\n", TEST_NAME);
printf("test_subscribe_ultrasound: \t %s\n", __test_print(test_subscribe_ultrasound()));
printf("test_read_ultrasound: \t %s\n", __test_print(test_read_ultrasound()));
printf("test_unsubscribe_ultrasound: \t %s\n", __test_print(test_unsubscribe_ultrasound()));
printf("test finished: %s has %u/%u tests passed\n\n", TEST_NAME, count_ok, count_all);
return (count_all - count_ok);
}
どのようにすることができます私はこれらのメソッドを呼び出すことができますか?私は私のCファイル内に私はそのようなオブジェクトインスタンス(それはすべての必要なALProxiesを生成する)を作成する可能性がないという意味ですか?
ヘルプは本当にいただければ幸いです... THX
は、これまでどうもありがとうございました!!
xtoflは..私は(別のCなしで、好ましく++オブジェクト)できるだけ簡単に私のインターフェイスを維持したいと思い言ったように:
#ifndef _ALDEBARAN_H
#define _ALDEBARAN_H
#ifdef __cplusplus
extern "C" {
#endif
void subscribe_ultrasound();
void unsubscribe_ultrasound();
float read_ultrasound();
#ifdef __cplusplus
}
#endif
#endif
問題はここsubscribe_ultrasound()のような機能をすることができないということですすべてのプロキシのインスタンス化せずに呼ばれる...これは私たちの前提条件である:
...
al_tts = this->getParentBroker()->getProxy("ALTextToSpeech");
al_led = this->getParentBroker()->getProxy("ALLeds");
al_motion = this->getParentBroker()->getProxy("ALMotion");
al_mem = this->getParentBroker()->getProxy("ALMemory");
al_us = this->getParentBroker()->getProxy("ALUltraSound");
al_cam = this->getParentBroker()->getProxy("NaoCam");
al_dcm = this->getParentBroker()->getProxy("DCM");
...
私はと呼ばれる上記のコードをお持ちでない場合は、他のすべてが失敗します。
その枠組みの中で、このコールのようなPythonスクリプトを経由して「自動ロード」私libaldebaran.soすることが可能である:フレームワークログ
myModule = ALProxy("Aldebaran", global_params.strRemoteIP, global_params.nRemotePort);
そして、こう述べています。
May 10 15:02:44 Hunter user.notice root: XXX: module aldebaran initiated
May 10 15:02:46 Hunter user.notice root: INFO: Registering module : 'Aldebaran'
May 10 15:02:46 Hunter user.notice root: ______ End of loading libraries ______
全く大丈夫です...それは私のモジュールのコンストラクタと呼ばれています(他のすべての必要なプロキシもインスタンス化されています)。
もちろん、この場合は
は多分他のすべてのプロセスにこれを共有する可能性がある...私のCプログラムに属していませんか?
私は「悪い」C++をC++の「良い」C++で包んでいないのではないかと不思議です。 –