Call a C varargs function from Java through JNA - variadic-functions

By the looks of these past issues and this documentation it appears doable, But how ?
My trials:
C
extern "C" GATEWAY_API void callIntoNative(LPCSTR evt_name, ...);
void callIntoNative(LPCSTR evt_name, ...)
//void callIntoNative(char* evt_name)
{
std::cout << evt_name << std::endl;
va_list vargs;
va_start(vargs, evt_name);
std::cout << va_arg(vargs, int) << " " << va_arg(vargs, double) << std::endl;
va_end(vargs);
}
Java
// public static native void callIntoNative(String evtName, Object[] varargs);
// public static native void callIntoNative(String evtName, Object... varargs);
//GateWay.callIntoNative("give me love", new Object[] {24, new String()});
Function callIntoNative = Function.getFunction("gateway.dll", "callIntoNative");
callIntoNative.invoke(new Object[]{new String("give me love"), new Integer(24), new Double(3.14)});
The output from Java program:
give me love
1374389535 1.18576e-322

Related

Non-member function and abstract class

So the objective is to create an abstract 'shape' class with 'rectangle' and 'triangle' as derived classes. Finishing the assignment with printing the perimeters and areas of a rectangle and triangle using a non-member function in main(). I'm having trouble on how to use just one non-member function, as opposed to making a print function for each type of shape:
void printPerimeter(Triangle triangle);
void printPerimeter(Rectangle rectangle);
//I'm trying not to do this
//what I had in mind, but don't know how to work this problem.
void printPerimeter(Shape shape)
{
float temp;
temp = shape.calcPerimeter();
cout << "Perimeter: " << temp << endl;
}
I know an abstract class can't be passed into a function, so how could I go about this?
class Shape
{
private:
public:
virtual void calcPerimeter()
{
cout << "Shape" << endl;
}
};
class Triangle1 : public Shape
{
public:
void calcPerimeter()
{
cout << "Triangle" << endl;
}
};
class Rectangle1 : public Shape
{
public:
void calcPerimeter()
{
cout << "Rectangle" << endl;
}
};
void printPerimeter(Shape* shape)
{
shape->calcPerimeter();
}
int main()
{
Shape *triangle = new Triangle1();
Shape *rectangle = new Rectangle1();
printPerimeter(triangle);
printPerimeter(rectangle);
return 0;
}
Please, check if this helps you to achieve your goal. Courtesy: #Retired Ninja

async_ read_until doesn't work as expected

So I am trying to write a program that reads and writes data through a tcp socket. I can successfully accept a connection, write data to it (though the write handler doesn't work as expected?). I also want to read data through the same socket - which doesnt seem to be working.
The class that handles all this is as follows:
using namespace boost::asio;
using namespace boost::asio::ip;
TcpServer::TcpServer(unsigned short port = 1700)
: ipPort(port){
tcp::acceptor acc(svc, tcp::endpoint(tcp::v4(), ipPort));
acc.listen();
acc.async_accept(socket, boost::bind(&TcpServer::Accept_Handler,this, placeholders::error));
SAY("Waiting for a New connection");
svc.run();
}
void TcpServer::Write_Handler(const boost::system::error_code& ec,
std::size_t bytes_transferred){
std::cout << ec.message() << std::endl;
if (!ec)
{
std::cout << "Just sent " << yawData << std::endl;
}
}
void TcpServer::Read_Handler(const boost::system::error_code& ec,
std::size_t bytes_transferred){
if (!ec)
{
std::string line;
std::istream is(&input_buffer_);
std::string test;
is >> test;
std::cout << "test" << test << std::endl;
std::getline(is, line);
if (!line.empty())
{
std::cout << "Recieved: " << line << std::endl;
}
}
else
std::cout << "Error reading:" << ec.message() << std::endl;
}
void TcpServer::Accept_Handler(const boost::system::error_code& ec){
if (!ec)
{
std::cout << "Accepted a connection! - Now switching to write mode " << std::endl;
connectMode = 1;
}
}
void TcpServer::Write_Data(){
if (connectMode){
SAY("Sent data");
std::ostringstream ss;
std::string sendBuffer;
ss << std::fixed << std::setprecision(2);
ss << yawData;
sendBuffer = ss.str() + "\r";
async_write(socket, buffer(sendBuffer), boost::bind(&TcpServer::Write_Handler, this,
placeholders::error,
placeholders::bytes_transferred));
}
}
void TcpServer::UpdateYaw(double data) {
yawData = data;
}
void TcpServer::Read_Data(){
if (connectMode){
async_read_until(socket, input_buffer_, "\n" , boost::bind(&TcpServer::Read_Handler, this,
placeholders::error,
placeholders::bytes_transferred));
}
}
TcpServer::~TcpServer(){
svc.stop();
}
The class header goes as:
class TcpServer {
private:
io_service svc;
tcp::socket socket{svc};
double yawData = 0;
unsigned short ipPort;
bool connectMode = 0;
streambuf input_buffer_;
void Write_Handler(const boost::system::error_code&,
std::size_t);
void Read_Handler(const boost::system::error_code&,
std::size_t);
void Accept_Handler(const boost::system::error_code&);
public:
TcpServer(unsigned short );
void Write_Data();
void Read_Data();
void UpdateYaw(double);
~TcpServer();
};
To use this, I call Write_Data(), followed by Read_Data(). Write_Data works, but the write handler isn't called - I can recieve data on the client side.
Read_Data() doesn't work at all. I know for sure that Data is being sent through the socket in teh format needed (ends with "\n")
Any ideas on what could possibly be wrong or, any debugging tips?
Thanks
EDIT
I plan to run the write_data and read_data functions from my main function as follows:
TcpServer *socketObj = new TcpServer(1700);
while ( i < 100 && trackObj->ReadTrackingState() != 0) {
SAY("Current Yaw - %.02f", trackObj->CurrentYaw());
socketObj->UpdateYaw(trackObj->CurrentYaw());
socketObj->Write_Data();
socketObj->Read_Data();
Platform::sleepMillis(1000);
i++;
}
void TcpServer::Accept_Handler(const boost::system::error_code &ec) {
if (!ec) {
std::cout << "Accepted a connection! - Now switching to write mode " << std::endl;
connectMode = 1;
}
}
This function ends the async processing. It doesn't schedule any more async work and therefore io_service::run() ends, as documented.
You want to chain directly or use io_service::work to keep the service running. I suggest the chaining:
void TcpServer::Accept_Handler(const boost::system::error_code &ec) {
if (!ec) {
std::cout << "Accepted a connection! - Now switching to write mode " << std::endl;
Write_Data();
}
}
But...
HOLD ON
You'll want to carefully review all the code.
void TcpServer::Write_Data() {
SAY("Sent data");
std::ostringstream ss;
std::string sendBuffer;
ss << std::fixed << std::setprecision(2);
ss << yawData;
sendBuffer = ss.str() + "\r";
async_write(socket, buffer(sendBuffer),
boost::bind(&TcpServer::Write_Handler, this, placeholders::error, placeholders::bytes_transferred));
}
What's going on here? First you create a temporary stream, fail to use it to append the carriage-return, and then pass the reference to a local string to async_write... That can't work. It's Undefined Behaviour.
A fix:
void TcpServer::Write_Data() {
SAY("Send data");
std::ostream ss(&output_buffer_);
ss << std::fixed << std::setprecision(2) << yawData << "\r";
async_write(socket, output_buffer_,
boost::bind(&TcpServer::Write_Handler, this, placeholders::error, placeholders::bytes_transferred));
}
DEMO
Live On Coliru
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <iomanip>
using namespace boost::asio;
using namespace boost::asio::ip;
template <typename T>
static inline void SAY(T&& v) { std::cout << std::forward<T>(v) << "\n"; }
class TcpServer {
private:
io_service svc;
tcp::socket socket{ svc };
double yawData = 0;
unsigned short ipPort;
streambuf input_buffer_, output_buffer_;
void Write_Handler(const boost::system::error_code &, std::size_t);
void Read_Handler(const boost::system::error_code &, std::size_t);
void Accept_Handler(const boost::system::error_code &);
public:
TcpServer(unsigned short = 1700);
void Write_Data();
void Read_Data();
void UpdateYaw(double);
~TcpServer();
};
TcpServer::TcpServer(unsigned short port) : ipPort(port) {
tcp::acceptor acc(svc, tcp::endpoint(tcp::v4(), ipPort));
acc.listen();
acc.async_accept(socket, boost::bind(&TcpServer::Accept_Handler, this, placeholders::error));
SAY("Waiting for a New connection");
svc.run();
}
void TcpServer::Write_Handler(const boost::system::error_code &ec, std::size_t /*bytes_transferred*/) {
std::cout << ec.message() << std::endl;
if (!ec) {
std::cout << "Just sent " << yawData << std::endl;
Read_Data();
}
}
void TcpServer::Read_Handler(const boost::system::error_code &ec, std::size_t /*bytes_transferred*/) {
if (!ec) {
std::cout << "Recieved: " << &input_buffer_ << std::endl;
} else
std::cout << "Error reading:" << ec.message() << std::endl;
}
void TcpServer::Accept_Handler(const boost::system::error_code &ec) {
if (!ec) {
std::cout << "Accepted a connection! - Now switching to write mode " << std::endl;
Write_Data();
}
}
void TcpServer::Write_Data() {
SAY("Send data");
std::ostream ss(&output_buffer_);
ss << std::fixed << std::setprecision(2) << yawData << "\r";
async_write(socket, output_buffer_,
boost::bind(&TcpServer::Write_Handler, this, placeholders::error, placeholders::bytes_transferred));
}
void TcpServer::UpdateYaw(double data) { yawData = data; }
void TcpServer::Read_Data() {
async_read_until(socket, input_buffer_, "\n", boost::bind(&TcpServer::Read_Handler, this, placeholders::error,
placeholders::bytes_transferred));
}
TcpServer::~TcpServer() { svc.stop(); }
int main() {
TcpServer server;
}

Copy constructor is being called instead of the move constructor

I'm trying to use the new C++11 move semantics, but the copy constructor gets called every time... Does anyone know what am I doing wrong? I'm using VS2012. Thanks in advance!
MemoryBlock::MemoryBlock(MemoryBlock& other)
: m_capacity(other.m_used), m_used(other.m_used), m_pointer(nullptr) {
std::wcout << L"Copy constructor called" << std::endl;
// ...
}
MemoryBlock& MemoryBlock::operator=(MemoryBlock& other) {
std::wcout << L"Copy assignment called" << std::endl;
if (this != &other) {
// ...
}
return *this;
}
MemoryBlock::MemoryBlock(MemoryBlock&& other)
: m_capacity(other.m_capacity), m_used(other.m_used), m_pointer(other.m_pointer) {
std::wcout << L"Move constructor called" << std::endl;
// ...
}
MemoryBlock& MemoryBlock::operator=(MemoryBlock&& other) {
std::wcout << L"Move assignment called" << std::endl;
if (this != &other) {
// ...
}
return *this;
}
MemoryBlock CreateRequest(const wchar_t *action) {
MemoryBlock request;
// ...
return request;
}
int __cdecl wmain(int argc, wchar_t *argv[]) {
// ...
MemoryBlock request = CreateRequest(argv[1]);
// ...
}

Runnable implementation using packaged_task in c++11

I am trying to create a Runnable interface in c++11 using packaged_task, with child class overriding run() function. I don't know why this code is not compiling. Its giving error related to type argument.
/usr/include/c++/4.8.1/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of()>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
Below is my code snippet. Could someone plz give me some information on this error and whether implementing Runnable this way is a right way to proceed ?
class Runnable {
public:
explicit Runnable() {
task_ = std::packaged_task<int()>(&Runnable::run);
result_ = task_.get_future();
std::cout << "starting task" << std::endl;
}
virtual int run() = 0;
int getResult() {
task_();
return result_.get();
}
virtual ~Runnable() {
std::cout << "~Runnable()" << std::endl;
}
private:
std::future<int> result_;
std::packaged_task<int()> task_;
};
class foo : public Runnable {
int fib(int n) {
if (n < 3) return 1;
else return fib(n-1) + fib(n-2);
}
public:
explicit foo(int n) : n_(n) {}
int run() {
cout << "in foo run() " << endl;
int res = fib(n_);
cout << "done foo run(), res = " << res << endl;
return res;
}
~foo() {}
private:
int n_;
};
int main(int argc, char*argv[]) {
stringstream oss;
oss << argv[1];
int n;
oss >> n;
shared_ptr<foo> obj(new foo(n));
obj->run();
cout << "done main" << endl;
return 0;
}

C++ passing an object to a function, the operator= is not called

So here is the code snippet:
class MyClass { public: MyClass(char chIn) { std::cout <<
"Constructor!" << std::endl; }
MyClass & operator= (char chIn) { std::cout << "Assigment
operator!" << std::endl; } } ;
void Func(MyClass objIn) { return; }
int _tmain(int argc, _TCHAR* argv[]) { Func('T'); system("PAUSE");
return 0; }
In the upper example the constructor of the object is called!!!! Why is this behavior? Shouldn't the assigment operator be called? Because we're assigning a value to the function parameter, aren't we?
operator= invoked for already existent object otherwise constructor(or copy constructor) is used to create needed instance

Resources