Go Back   Northcode Support > SWF Studio Plugin Development
FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Search this Thread Display Modes
Old 2006-07-26, 12:20 AM   #1
enaizi
Registered User
 
Join Date: Dec 2002
Location: Malaysia
Posts: 12
Plugin VC++ problem

I'm trying the V3 Plugin to read information from smart card reader. However the value passed to SS did not come out correct.

extern "C" MYKAD_API int myKadOpen(void){
int nResult = CardOpen(); //open reader
return nResult;
}


When the return value is int, the value passed to SS come out OK.


extern "C" MYKAD_API LPCTSTR myKadRead(void){
int nResult = SelJPNApp(); //select JPN application in card
BYTE name[150] = "\0";
nResult = JPN_OrgName(name); //read MyKadName

LPCTSTR result = "hello world";
//LPCTSTR result = (char*) name;
//LPCTSTR result = reinterpret_cast<LPCTSTR>(name);

MessageBox(NULL, result, "myKad Information", MB_OK);

return result;
}


When passing "Hello World" no problem.
When using (char*) or cast, message box displays actual value but the
value passed to SS comes out as &

Any idea how to solve this?
enaizi is offline   Reply With Quote
Old 2006-07-26, 01:55 AM   #2
northcode
Tim
 
northcode's Avatar
 
Join Date: May 2001
Location: Ottawa
Posts: 11,873
This isn't really a V3 plugin problem, it's a pointer problem.

You can't return a pointer to name, it exists on the stack, which is cleaned up as soon as you leave the myKadOpen function (so the pointer is to random garbage). You can verify this for your self with a simple test.

Code:
LPTSTR test(void)
{
   BYTE name[150] = "whatever\0";
   LPTSTR result = (LPTSTR)name;
   MessageBox(NULL, result, "in test", MB_OK); // this works
   return result; 
}

void main(void)
{
   LPTSTR s = test();
   MessageBox(0, s, "in main", 0); // this fails
   free(s);
}
You need to make sure that the pointer you return points to something that will survive the end of the function it lives in. You can malloc or new up some memory or use strdup, like this...

Code:
LPTSTR test(void)
{
   BYTE name[150] = "whatever\0";
   LPTSTR result = (LPTSTR)strdup((LPTSTR)name);
   MessageBox(NULL, result, "in test", MB_OK); // this still works
   return result; 
}

void main(void)
{
   LPTSTR s = test();
   MessageBox(0, s, "in main", 0); // now this will work too
   free(s);
}
northcode is offline   Reply With Quote
Old 2006-07-26, 02:25 AM   #3
enaizi
Registered User
 
Join Date: Dec 2002
Location: Malaysia
Posts: 12
Smile Thank you guys. You're the BEST !!!

Never done anything in C++ before but the V3 Plugin sample and your help makes it very easy.

Thank you again
enaizi is offline   Reply With Quote
Old 2006-07-26, 09:32 AM   #4
northcode
Tim
 
northcode's Avatar
 
Join Date: May 2001
Location: Ottawa
Posts: 11,873
One last thing, I forgot to free the pointer that was returned from the test function. That would have leaked memory on every call to test. Not good. I fixed the examples I posted earlier.

Note: Freeing the pointer in the first example (where the pointer is just garbage) is just as likely to crash your application as fail silently, depending on where it's pointing. Pointers in C/C++ aren't hard, the rules are simple, when you break them the compiler makes you pay

Here are a couple of places you can start reading about pointers, but if you're going to be writing plugins I'd suggest picking up a good beginners book on C/C++.

A tutorial on pointers and arrays in C

A Beginner's Guide to Pointers
northcode is offline   Reply With Quote
Old 2006-07-27, 08:49 PM   #5
enaizi
Registered User
 
Join Date: Dec 2002
Location: Malaysia
Posts: 12
Generic CallDll

That helps a lot and I managed to get the interface to smartcard reader to work.

To make it easier for us to connect to external dll, would it be possible to have a generic CallDll plugin that accepts 3 parameters, ie the dll name, input and result.

The CallDll pass the parameters to myDll which can call the external dll, pass the input parameters and send back the result to CallDll.

In this way, we can add any call to dll directly without having to modify and recompile the dll.

I hope nc can help.

Thank you.
enaizi is offline   Reply With Quote
Old 2006-07-27, 09:03 PM   #6
northcode
Tim
 
northcode's Avatar
 
Join Date: May 2001
Location: Ottawa
Posts: 11,873
To make a generic DLL calling plugin is a little tricky because you have to manage the call stack yourself instead of just calling a function. If all the functions in the DLL you want to call have the same signature i.e. take the same number and type of parameters and return the same type of value, then the job gets a LOT easier. It's still manageable as long as you know the signatures of the functions you want to call ahead of time.

You need at least 4 parameters for a generic function caller (i) the name of the DLL to use with LoadLibrary (ii) the name of the function to pass to GetProcAddress (iii) the input parameter(s) and (iv) the return variable.

This is how the CallDll example plugin works it just has one function for each function you want to call. Since you can have optional input parameters you could actually do this all with one function and just use the function name to determine how to construct the call.
northcode is offline   Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes