Question

I'm attempting to troubleshoot the sendmulti function (loops through sending parts of a char array to serial port) in jUART (https://github.com/billhsu/jUART).

That specific function isn't registered with the .dll that's already built in the repository. I downloaded & rebuilt without changing anything, registered the new .dll with regsvr32 and replaced the old .dll with the newly rebuilt one.

Now the function is registered and can be called, but I'm getting a few errors depending on the input I provide.

First error:

ser.sendmulti("Sc48E");
 Error in event handler: Error: Error calling method on NPObject.
ser.getLastException();
 "Error: Argument 2is not optional."

So I added a second argument, and now I get:

ser.sendmulti("Sc48E", 2);
 Error: Error calling method on NPObject.
ser.getLastException();
 "Invalid argument conversion from class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > to class boost::shared_ptr<class FB::JSAPI> at index 1"

Not really sure where to go from there (not an experienced dev at all), so I'm turning to the community to see what should be looked into next or if someone can dive into jUART with me to find the fix.

The obviously related functions for sendmulti that I can find:

SerialAPI.h

void sendmulti(const FB::JSObjectPtr& msg, int length)
    {
        unsigned char *message = new unsigned char[length];
        FB::variant v;
        for(int i = 0; i < length; i++)
        {
            v = msg->GetProperty(i);
            message[i] = v.convert_cast<unsigned char>();
        }

        io.post(boost::bind(&SerialAPI::do_multi_send, this, (char *)message, length));

void do_multi_send(const char msg[], int length);
void send_multi_start(int length);

SerialAPI.cpp

void SerialAPI::do_multi_send(const char msg[], const int length) 
{
    bool write_in_progress = !send_msg.empty(); // is there anything currently being written? 
    for(int i = 0; i < length; i++)
    {
        send_msg.push_back(msg[i]); // store in write buffer 
    }

    if (!write_in_progress) // if nothing is currently being written, then start 
        send_multi_start(length); 
}

void SerialAPI::send_multi_start(int length) 
{
    boost::asio::async_write(serial, 
    boost::asio::buffer(&send_msg.front(), length), 
    boost::bind(&SerialAPI::send_multi_complete, 
    this, 
    boost::asio::placeholders::error)); 
}

I think those are the immediate relevant functions, though it's worth noting that the send() function (sends just a single byte) worked ok with the first .dll and gives the same error with the newly-built .dll:

void SerialAPI::do_send(const char msg) 
{
    bool write_in_progress = !send_msg.empty(); // is there anything currently being written? 
    send_msg.push_back(msg); // store in write buffer 
    if (!write_in_progress) // if nothing is currently being written, then start 
        send_start(); 
} 

Thanks!

*Working Code*

SerialAPI.h

void sendmulti(const std::string& msg)
{
    io.post(boost::bind(&SerialAPI::do_multi_send, this, msg));
}

void do_multi_send(const std::string& msg);

SerialAPI.cpp

void SerialAPI::do_multi_send(const std::string& msg) 
{
    bool write_in_progress = !send_msg.empty(); // is there anything currently being written? 

    const int sLength = msg.length();

    for(int i = 0; i < sLength; i++) {
        const char cMsg = msg[i];
        send_msg.push_back(cMsg); // store in write buffer 

        if (!write_in_progress) // if nothing is currently being written, then start 
            send_multi_start(sLength); 
    }

void SerialAPI::send_multi_start(int sLength) 
{
    boost::asio::async_write(serial, 
    boost::asio::buffer(&send_msg.front(), sLength), 
    boost::bind(&SerialAPI::send_multi_complete, 
    this, 
    boost::asio::placeholders::error)); 
}

That's what works. Any recommendations for optimizing what I have?

Thanks!

Was it helpful?

Solution

It's already telling you exactly what is happening. You put a FB::JSObjectPtr& type as the first parameter, but then you pass in a string for that parameter; it can't convert a string to a javascript object, so it fails.

I really don't understand why sendMulti would possibly be doing what it is doing; it's expecting a string in an array of characters, ['l','i','k','e',' ','t','h','i','s']. Why would you do that? It seems a little weird to me.

Instead, why don't you just change the first parameter of sendMulti to a const std::string& and use the string as it's passed in?

I suppose for completeness I should say that you can probably make it work the currently way by calling it like this:

var strArray = "Sc48E".split('');
ser.sendmulti(strArray, strArray.length);

... note that this is really inefficient because it has to call back into javascript to get each character, instead of just getting the string all in one chunk.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top