I have a c++ code which has been connected to a visual basic user interface by someone else. Here is one of the functions code that connects c++ to visual basic:
extern "C" void PASCAL EXPORT RCS( stAct* act,stResourceDirectory* resDir, stCalendar* calendar, short numOfAct, short numOfRes, short numOfCal, int nDataDate )
{
Network network;
short id;
Activity* p_act;
node<Activity>* p_node;
// Setting
network.create_calendars (calendar, numOfCal);
network.set_data_date (nDataDate);
set_activity(network, act, numOfAct );
// only for id, duration, and description
set_resource(network, act, resDir, numOfAct, numOfRes);
// create resource profile and add required resource for every activity
network.CPM ();
p_node = network.get_network_head_p();
while (p_node != NULL ) {
p_act = p_node->refer_data();
id = p_act->get_ID ();
act[id].TF_in_CPM = p_act->get_TF_min ();
act[id].FF_in_CPM = p_act->get_FF();
act[id].EST_in_CPM = p_act->get_EST ();
act[id].EFT_in_CPM = p_act->get_EFT ();
act[id].LST_in_CPM = p_act->get_LST ();
act[id].LFT_in_CPM = p_act->get_LFT ();
p_node = p_node->get_link();
}
network.RCS();
p_node = network.get_network_head_p();
while (p_node != NULL ) {
p_act = p_node->refer_data();
id = p_act->get_ID ();
act[id].TF_in_RCS = p_act->get_TF_min ();
act[id].FF_in_RCS = p_act->get_FF();
act[id].EST_in_RCS = p_act->get_EST ();
act[id].EFT_in_RCS = p_act->get_EFT ();
act[id].LST_in_RCS = p_act->get_LST ();
act[id].LFT_in_RCS = p_act->get_LFT ();
p_node = p_node->get_link();
}
}
I want to replace the visual basic part with a Java GUI and it seems confusing for me to write the connection code. Is there anyone who can help me call three c++ functions with passing arguments to the native method and receiving results from it, by JNA/ SWIG/ Runtime or any other methods you think it would work easier and better?
Here is an instructional example to help get you started. In this snippet, Java2Win64 is the DLL that contains the native code to execute. Function functionMaryam() takes 1 param as int and returns an int. Easy to expand for any data type.
public class JnaExampleMaryam {
// ------------------------------------------
// Java2Win.class
// ------------------------------------------
public interface Java2Win extends Library {
Java2Win call = (Java2Win) Native.loadLibrary("Java2Win64", Java2Win.class);
int functionMaryam(int i);
}
// ------------------------------------------
// ------------------------------------------
// Test
// ------------------------------------------
public static void main(final String args[]) throws Exception {
final File file = new File("rootToDLL", "Java2Win64.dll");
LibraryLoader.loadLibrary(file);
int result = Java2Win.call.functionMaryam(42);
}
// ------------------------------------------
Related
I'm trying to use a factory pattern to create different types of "State" objects. The objects are returned with a pointer (State*) but shortly after the objects are created, the values they point to disappear (go to NULL or reset to boolean "true").
The code directly below is where it goes awry, but below that is a complete code sample that compiles and runs. Additionally, I've posted pictures of the debugger values before and after the usleep() command.
I feel like it may have something to do with scope and the garbage collector, but I'm not a C++ expert by any stretch of the imagination. I would have thought my pointer would have kept my referenced object alive.
// relevant code
void execute(){
// Calling the constructor directly as an example
State directState = State("temp", false, false, false);
// Using factory pattern to create a state. Just creating the "default" state as an example
State * factoryState = StateFactory::getDefaultState();
// factoryState -> name is "Reading" in the debugger, but when I try to print it out, it's gone
// Grab the names for easy reference
const char * dName = directState.name;
const char * fName = factoryState -> name;
usleep(1000000 / 100);
// factoryState -> name .... it's vanished?
usleep(1000000 / 100);
// TODO we would run the factoryState -> execute() function here
}
// Complete code example
#include <iostream>
#include <zconf.h>
// Main generic "State" class
class State {
public:
const char * name;
bool isReadable;
bool isExecuting;
bool isFinished;
State(const char name[], bool isReadable, bool isExecuting, bool isFinished){
this -> name = name;
this -> isReadable = isReadable;
this -> isExecuting = isExecuting;
this -> isFinished = isFinished;
}
};
// An inherited class. There will be lots of these eventually
class StateReading: public State { ;
public:
StateReading():State((const char *)"Reading", true, false, false) {}
};
// Factory method that will create lots of the different states
// note that it will be returning a pointer to a "State" object
class StateFactory {
public:
static State* getDefaultState(){
StateReading defaultState = StateReading();
State* state = &defaultState;
return state;
}
};
// Runs the various "States" in a template pattern
class StateExecutor {
public:
State * state;
StateExecutor(){
StateReading stateReading = StateReading();
state = &stateReading;
}
void execute(){
// Calling the constructor directly as an example
State directState = State("temp", false, false, false);
// Using factory pattern to create a state. Just creating the "default" state as an example
State * factoryState = StateFactory::getDefaultState();
// factoryState -> name is "Reading" in the debugger, but when I try to print it out, it's gone
// Grab the names for easy reference
const char * dName = directState.name;
const char * fName = factoryState -> name;
usleep(1000000 / 100);
// factoryState -> name .... it's disappeard?
usleep(1000000 / 100);
// TODO we would run the factoryState -> execute() function here
}
};
// The actual
void loop(StateExecutor stateExecutor) {
// Run the "execute" function of whatever the current state is
// The stateExecutor actually runs the state
stateExecutor.execute();
// Slow the loop down a little. Just for effect
usleep(1000000 / 100);
}
// Simple program to recreate an event loop
int main() {
try {
StateExecutor stateExecutor = StateExecutor();
int count = 0;
do {
loop(stateExecutor);
count++;
// Arbitrarily break out of the loop after 100 events.
} while(count < 100);
} catch (std::exception& e){
std::cout << e.what() << '\n';
}
}
Here are the values directly after the factory created them. All looks good.
Gah! I called usleep() and the factoryState's name field is gone and the bools have reverted to true (cout does this as well). Black magic!
Here:
static State* getDefaultState(){
StateReading defaultState = StateReading();
State* state = &defaultState;
return state;
}
You return a pointer to defaultState. This state however is destroyed when the function returns. Using this pointer later is undefined behavior. You can declare defaultState as static, though i would rather make it a static member.
I'm coding a plugin for XPLANE10 which gets a MSG from ROS.
My IDE is QTcreator 4.1.0 based QT 5.7.0 for Ubuntu 64 Bit. I would like to use C++11 Standards
My code explained
The main initializes ROS and creates a map -> container.
ROS spins in a loop till my GUI sends a MSG where my AirPlane should fly.
The MSG contains 3 floats(phi, theta, psi) where "phi" is the AirPlane ID, theta contains the ID for my ETA(Estimated Time of Arrival)
and psi contains the ID for my pose All of the IDs are saved in the ParameterServer(lookuptable).
So at the beginning i look up the activeAirplanes which returns a vector . I would like to store them in a map where the key is the AirCraft ID and the second param is an instance of the Object.
So i have initialized the for example(looked in container while debugging):
[0] first = 1 // Airplane ID1
[0] second = new CObject(freq)
[1] first = 2 // Airplane ID2
[1] second = new CObject(freq)
If i get a MSG from GUI
phi = 1
theta=2
psi=3
,
ROS will callback
MSG(....std::map<i32, CObject> &container)
// if phi is 1 so use the mapkey 1 and trigger the method do_stuff from CObject
do_stuff(phi, theta, psi,freq)
I would like to call the in a function from main
int getPlanes(std::map<i32,CObject>& container)
{
...
getActiveAirplanesFromServer(activePlanes);
}
First Question:
How do i pass the container to my callback?
Second Question:
How do i parallelize do_stuff() so my callback will return to main and i'm able to command more aircrafts while the others are calculated?
Third Question:
How would be the correct syntax for getPlanes to pass the container by reference so getPlanes() can edit it?
Fourth Question:
Is there a difference between
std::map<i32,CObject*> map
std::map<i32,CObject>* map
and
std::map<i32,CObject*>::iterator it=container->begin();
std::map<i32,CObject*>::iterator* it=container->begin();
If yes, what do i want ? #4Solved
// I have to edit stuff 'cause of some restrictions in my company.
#include "Header.h"
int main()
{
f64 freq = 10;
std::map<i32, CObject>* container;
std::map<i32,CObject>::iterator* it=container->begin();
// ROS
if(!ros::isInitialized())
{
int rosargc = 0;
char** rosargv = NULL;
ros::init(rosargc, rosargv, "MainNode");//), ros::init_options::AnonymousName);
}
else
{
printf("Ros has already been initialized.....\n");
}
ros::NodeHandle* mainNodeHandle=new ros::NodeHandle;
ros::AsyncSpinner spinner(2);
ParameterServer * ptrParam= new ParameterServer(mainNodeHandle);
ros::Subscriber airSub=mainNodeHandle->subscribe<own_msgs::ownStruct>("/MSG",
1000,
boost::bind(MSG,
_1,
freq,
container));
std::vector<i32> activePlanes;
i32 retVal=0;
retVal += ptrParam-> ParameterServer::getActiveAirplanesFromServer(activePlanes);
if (retVal == 0 && activePlanes.size()>0)
{
for (u32 j =0; j <activePlanes.size(); j++)
{
container->insert (std::pair<i32,CObject> (activePlanes[j] , new CObject(freq)));
}
}
while (ros::ok())
{
spinner.start(); //spinnt sehr viel :-)
ros::waitForShutdown ();
}
std::cout<<"ENDE"<<std::endl;
int retval = 1;
return retval;
}
void MSG(const own_msgs::ownStruct<std::allocator<void> >::ConstPtr &guiMSG,
f64 freq,
std::map<i32, CObject> &container)
{
if ((guiMSG->phi != 0) && (guiMSG->theta != 0) && (guiMSG->psi != 0))
{
std::string alpha = std::to_string(guiMSG->phi)+std::to_string(guiMSG->theta)+to_string(guiMSG->psi);
container.at(guiMSG->phi) -> do_stuff(guiMSG->phi,guiMSG->theta,guiMSG->psi, freq);
}
else
{
std::cout<<" Did not receive anything\n"<<endl;
}
}
void do_stuff(...)
{
//copy the IDs to private Member of this single Object
//setROS() for this single Object
//callback the current AC pose via ID from XPLANE
//callback the wished AC pose via ID from ParamServer
// do some calculations for optimum flight path
// publish the Route to XPlane
}
EDIT::
Problem is i get it to compile now and if debug it and set a breakpoint at :
void MSG(const own_msgs::ownStruct<std::allocator<void> >::ConstPtr &guiMSG,f64 freq,std::map<i32, CObject*> &container)
{
..
/*->*/ container.at(guiMSG->)...
}
The Container remains empty.
So i read some stuff about pointers and i saw my errors..
I confused * and &
if i want to pass the adress of a variable i have to write like
int main()
{
int a = 0;
AddTwo(&a)
cout<<a<<endl; // Output: 2
}
void AddTwo(int* a)
{
a+=2;
}
I'm learning C# and have some experience with it. For a small project I need to implement a C++ dll into my C# app. It is a licenseplate recognition sdk.I can initialize it, so calling to this C++ code is working. But I have a problem to receive a struct back from the c++ code with strings in it. I tried a lot, read here a lot, but I don't get it working. This is C# side:
[DllImport("D:\\processor.dll", EntryPoint = "StartALPR", CallingConvention = CallingConvention.Cdecl)]
[return:MarshalAs(UnmanagedType.LPStruct)]
public static extern TMyData StartALPR(TImageSource tImageSource);
The C# struct TMyData :
[StructLayout(LayoutKind.Sequential)]
public struct TMyData
{
[MarshalAs(UnmanagedType.LPTStr)]
public string PlateString;
[MarshalAs(UnmanagedType.LPTStr)]
public string PlateXML;
[MarshalAs(UnmanagedType.LPTStr)]
public string LastError;
};
And this is the method we call to send tImageSource which contains a string with a filepath to an image to analyze.
alprResult = StartALPR(tImageSource);
The file is analyzed, so that's working. I can see the plate strings in the output of VS2015.
But I'm expecting a struct "alprResult" back as defined in TMydata, but I get an exception that the method sign is not compatible with the pinvoke sign. The only information I have is an example of how to use this dll/code in C++. This is the C++ code :
TImageSource SImageSource;
TMyData *pd;
/* Set input image */
SImageSource.MyImageFile = AnsiString(CarImage).c_str();
Memo1->Lines->Clear();
/* Starting plate detect and recognition */
pd = StartALPR(&SImageSource);
/* Standard XML result, the plate datas with numbers and positions */
Memo1->Lines->Add(pd->PlateXML);
/* last error message */
Memo2->Lines->Add(pd->LastError);
/* Best characters on plate */
Edit1->Text = pd->PlateString;
This is the C++ struct from the same example :
struct TMyData;
typedef TMyData *PMyData;
struct TMyData
{
/**
PlateString: Best license plate number of the plate group
*/
const char * PlateString;
/**
PlateXML: Plate group data in standard XML string
*/
const char * PlateXML;
/**
LastError: Laast config error ex: bad file extensions .. Default: empty
*/
const char * LastError;
};
How can I use this in C#?
Thanks in advance.
I actually had to solve a similar issue to this recently. I simply serialized the data into a struct and shipped it over a local zeromq socket.
//
// Weather update server in C++
// Binds PUB socket to tcp://*:5556
// Publishes random weather updates
//
// Olivier Chamoux <olivier.chamoux#fr.thalesgroup.com>
//
#include <zmq.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#if (defined (WIN32))
#include <zhelpers.hpp>
#endif
#define within(num) (int) ((float) num * random () / (RAND_MAX + 1.0))
int main () {
// Prepare our context and publisher
zmq::context_t context (1);
zmq::socket_t publisher (context, ZMQ_PUB);
publisher.bind("tcp://*:5556");
publisher.bind("ipc://weather.ipc"); // Not usable on Windows.
// Initialize random number generator
srandom ((unsigned) time (NULL));
while (1) {
int zipcode, temperature, relhumidity;
// Get values that will fool the boss
zipcode = within (100000);
temperature = within (215) - 80;
relhumidity = within (50) + 10;
// Send message to all subscribers
zmq::message_t message(20);
snprintf ((char *) message.data(), 20 ,
"%05d %d %d", zipcode, temperature, relhumidity);
publisher.send(message);
}
return 0;
}
and now the client
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using ZeroMQ;
namespace Examples
{
static partial class Program
{
public static void WUClient(string[] args)
{
//
// Weather update client
// Connects SUB socket to tcp://127.0.0.1:5556
// Collects weather updates and finds avg temp in zipcode
//
// Author: metadings
//
if (args == null || args.Length < 2)
{
Console.WriteLine();
Console.WriteLine("Usage: ./{0} WUClient [ZipCode] [Endpoint]", AppDomain.CurrentDomain.FriendlyName);
Console.WriteLine();
Console.WriteLine(" ZipCode The zip code to subscribe. Default is 72622 Nürtingen");
Console.WriteLine(" Endpoint Where WUClient should connect to.");
Console.WriteLine(" Default is tcp://127.0.0.1:5556");
Console.WriteLine();
if (args.Length < 1)
args = new string[] { "72622", "tcp://127.0.0.1:5556" };
else
args = new string[] { args[0], "tcp://127.0.0.1:5556" };
}
string endpoint = args[1];
// Socket to talk to server
using (var context = new ZContext())
using (var subscriber = new ZSocket(context, ZSocketType.SUB))
{
string connect_to = args[1];
Console.WriteLine("I: Connecting to {0}…", connect_to);
subscriber.Connect(connect_to);
/* foreach (IPAddress address in WUProxy_GetPublicIPs())
{
var epgmAddress = string.Format("epgm://{0};239.192.1.1:8100", address);
Console.WriteLine("I: Connecting to {0}…", epgmAddress);
subscriber.Connect(epgmAddress);
}
} */
// Subscribe to zipcode
string zipCode = args[0];
Console.WriteLine("I: Subscribing to zip code {0}…", zipCode);
subscriber.Subscribe(zipCode);
// Process 10 updates
int i = 0;
long total_temperature = 0;
for (; i < 20; ++i)
{
using (var replyFrame = subscriber.ReceiveFrame())
{
string reply = replyFrame.ReadString();
Console.WriteLine(reply);
total_temperature += Convert.ToInt64(reply.Split(' ')[1]);
}
}
Console.WriteLine("Average temperature for zipcode '{0}' was {1}°", zipCode, (total_temperature / i));
}
}
}
}
When calling WinAPI functions that take callbacks as arguments, there's usually a special parameter to pass some arbitrary data to the callback. In case there's no such thing (e.g. SetWinEventHook) the only way we can understand which of the API calls resulted in the call of the given callback is to have distinct callbacks. When we know all the cases in which the given API is called at compile-time, we can always create a class template with static method and instantiate it with different template arguments in different call sides. That's a hell of a work, and I don't like doing so.
How do I create callback functions at runtime so that they have different function pointers?
I saw a solution (sorry, in Russian) with runtime assembly generation, but it wasn't portable across x86/x64 archtectures.
You can use the closure API of libffi. It allows you to create trampolines each with a different address. I implemented a wrapping class here, though that's not finished yet (only supports int arguments and return type, you can specialize detail::type to support more than just int). A more heavyweight alternative is LLVM, though if you're dealing only with C types, libffi will do the job fine.
I've come up with this solution which should be portable (but I haven't tested it):
#define ID_PATTERN 0x11223344
#define SIZE_OF_BLUEPRINT 128 // needs to be adopted if uniqueCallbackBlueprint is complex...
typedef int (__cdecl * UNIQUE_CALLBACK)(int arg);
/* blueprint for unique callback function */
int uniqueCallbackBlueprint(int arg)
{
int id = ID_PATTERN;
printf("%x: Hello unique callback (arg=%d)...\n", id, arg);
return (id);
}
/* create a new unique callback */
UNIQUE_CALLBACK createUniqueCallback(int id)
{
UNIQUE_CALLBACK result = NULL;
char *pUniqueCallback;
char *pFunction;
int pattern = ID_PATTERN;
char *pPattern;
char *startOfId;
int i;
int patterns = 0;
pUniqueCallback = malloc(SIZE_OF_BLUEPRINT);
if (pUniqueCallback != NULL)
{
pFunction = (char *)uniqueCallbackBlueprint;
#if defined(_DEBUG)
pFunction += 0x256; // variable offset depending on debug information????
#endif /* _DEBUG */
memcpy(pUniqueCallback, pFunction, SIZE_OF_BLUEPRINT);
result = (UNIQUE_CALLBACK)pUniqueCallback;
/* replace ID_PATTERN with requested id */
pPattern = (char *)&pattern;
startOfId = NULL;
for (i = 0; i < SIZE_OF_BLUEPRINT; i++)
{
if (pUniqueCallback[i] == *pPattern)
{
if (pPattern == (char *)&pattern)
startOfId = &(pUniqueCallback[i]);
if (pPattern == ((char *)&pattern) + sizeof(int) - 1)
{
pPattern = (char *)&id;
for (i = 0; i < sizeof(int); i++)
{
*startOfId++ = *pPattern++;
}
patterns++;
break;
}
pPattern++;
}
else
{
pPattern = (char *)&pattern;
startOfId = NULL;
}
}
printf("%d pattern(s) replaced\n", patterns);
if (patterns == 0)
{
free(pUniqueCallback);
result = NULL;
}
}
return (result);
}
Usage is as follows:
int main(void)
{
UNIQUE_CALLBACK callback;
int id;
int i;
id = uniqueCallbackBlueprint(5);
printf(" -> id = %x\n", id);
callback = createUniqueCallback(0x4711);
if (callback != NULL)
{
id = callback(25);
printf(" -> id = %x\n", id);
}
id = uniqueCallbackBlueprint(15);
printf(" -> id = %x\n", id);
getch();
return (0);
}
I've noted an interresting behavior if compiling with debug information (Visual Studio). The address obtained by pFunction = (char *)uniqueCallbackBlueprint; is off by a variable number of bytes. The difference can be obtained using the debugger which displays the correct address. This offset changes from build to build and I assume it has something to do with the debug information? This is no problem for the release build. So maybe this should be put into a library which is build as "release".
Another thing to consider whould be byte alignment of pUniqueCallback which may be an issue. But an alignment of the beginning of the function to 64bit boundaries is not hard to add to this code.
Within pUniqueCallback you can implement anything you want (note to update SIZE_OF_BLUEPRINT so you don't miss the tail of your function). The function is compiled and the generated code is re-used during runtime. The initial value of id is replaced when creating the unique function so the blueprint function can process it.
I am trying make Unit test with Unit test wizard, but I am always getting:
Test method TestProject9.Log_InsertMasterTest threw exception:
System.NullReferenceException: Object reference not set to an instance of an object.
My test.cs:
[TestMethod()]
[DeploymentItem("Engine.dll")]
public void Log_InsertMasterTest()
{
SkinnedRepairSearch_Accessor target = new SkinnedRepairSearch_Accessor(); // TODO: Initialize to an appropriate value
int RepairMasterID = 0; // TODO: Initialize to an appropriate value
int RepairMasterIDOld = 0; // TODO: Initialize to an appropriate value
int id = 0; // TODO: Initialize to an appropriate value
string Text = string.Empty; // TODO: Initialize to an appropriate value
target.Log_InsertMaster(RepairMasterID, RepairMasterIDOld, id, Text);
Assert.Inconclusive("A method that does not return a value cannot be verified.");
}
Log_InsertMaster method:
protected void Log_InsertMaster(int RepairMasterID, int RepairMasterIDOld, int id, string Text)
{
SqlConnection myConnection = new SqlConnection(Globals.DatabaseConnectionString);
SqlCommand myCommand = new SqlCommand("dbo.Repair_LogInsertMaster", myConnection);
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.Add("#RepairMasterID", SqlDbType.Int).Value = RepairMasterID;
myCommand.Parameters.Add("#RepairMasterIDold", SqlDbType.Int).Value = RepairMasterIDOld;
myCommand.Parameters.Add("#DateTime", SqlDbType.DateTime).Value = System.DateTime.Now;
myCommand.Parameters.Add("#RepairID", SqlDbType.Int).Value = id;
myCommand.Parameters.Add("#UserSignature", SqlDbType.NVarChar, 200).Value = AdminUser.Signature;
myCommand.Parameters.Add("#Text", SqlDbType.NVarChar, 200).Value = Text;
myConnection.Open();
myCommand.ExecuteNonQuery();
myConnection.Close();
}
How to not get this error? And how to use Unint testing wizard?
Exception line:
SkinnedRepairSearch_Accessor target = new SkinnedRepairSearch_Accessor(); // TODO: Initialize to an appropriate value
I tried and other, public method:
[TestMethod()]
public void EmptyTextBoxesTest()
{
SkinnedRepair target = new SkinnedRepair(); // TODO: Initialize to an appropriate value
Control parent = null; // TODO: Initialize to an appropriate value
target.EmptyTextBoxes(parent);
Assert.Inconclusive("A method that does not return a value cannot be verified.");
}
same error