using PB-made dll in MSVSC++12/13 project - unicode problem

Windows specific forum
broozar
User
User
Posts: 61
Joined: Sat May 08, 2010 11:21 pm
Location: Berlin, Germany

Re: using PB-made dll in MSVSC++12/13 project - unicode prob

Post by broozar »

TI-994A wrote:make sure that the DLL is receiving the values lc, pc, bl properly
it does. it also translates correctly (blue messagebox below). the error must be in the return:

Image

both red underlined strings should be the same.

in fact, the return value of the translated string in MSVS looks exactly like this nonsense string, so either PB transmits it incorrectly, or MSVS reads it incorrectly.
User avatar
TI-994A
Addict
Addict
Posts: 2741
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: using PB-made dll in MSVSC++12/13 project - unicode prob

Post by TI-994A »

broozar wrote:...the return value of the translated string in MSVS looks exactly like this nonsense string, so either PB transmits it incorrectly, or MSVS reads it incorrectly.
So, pg_translate() receives the three parameters properly, but the returned string, pg_returnTranslatedString, is garbled?

Which module is displaying that message box; PureBasic or VS2013?
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
broozar
User
User
Posts: 61
Joined: Sat May 08, 2010 11:21 pm
Location: Berlin, Germany

Re: using PB-made dll in MSVSC++12/13 project - unicode prob

Post by broozar »

TI-994A wrote:So, pg_translate() receives the three parameters properly, but the returned string, pg_returnTranslatedString, is garbled?
exactly. step by step:

1. MSVS feeds parameters into pg_translate into the PB DLL
2. pg_translate receives it, does PeekS with utf8, and translates the string: that is where the blue message box pops up (LC: "LANGCODE.s", CS: "CODESTRING.s" are the 2 input strings, RET: is the translated return string pg_returnTranslatedString) - everything is correct up to this point.
3. pg_translate returns the string as const char* to MSVS, where it looks garbled like in the dark window in the screenshot
User avatar
TI-994A
Addict
Addict
Posts: 2741
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: using PB-made dll in MSVSC++12/13 project - unicode prob

Post by TI-994A »

broozar wrote:...that is where the blue message box pops up (LC: "LANGCODE.s", CS: "CODESTRING.s" are the 2 input strings, RET: is the translated return string pg_returnTranslatedString)

Code: Select all

  If pg_bInit = 1
    If FindMapElement(languageDict(), LANGCODE)
      If bLC = 0
        pg_returnTranslatedString = languageDict(LANGCODE)\dict(CODESTRING)
      Else
        pg_returnTranslatedString = LCase(languageDict(LANGCODE)\dict(CODESTRING))
      EndIf
    Else
      pg_returnTranslatedString = "NOCODE"
    EndIf
  Else
    pg_returnTranslatedString = "NOINIT"
  EndIf
From the snippet above, pg_returnTranslatedString is a PureBasic-generated string. If PureBasic is not displaying its own strings in its own message box properly, there may some issue with your platform or character-set configurations.

All corresponding modules must be compiled on the same architecture (32bit or 64bit), and must also be configured for the same character set; UNICODE for your requirements. You'll have to resolve this first.

Following your examples, I'm able to send and receive the strings, and display them on either side properly.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
broozar
User
User
Posts: 61
Joined: Sat May 08, 2010 11:21 pm
Location: Berlin, Germany

Re: using PB-made dll in MSVSC++12/13 project - unicode prob

Post by broozar »

TI-994A wrote:If PureBasic is not displaying its own strings in its own message box properly
PB does display everything correctly in its own message box, as proven by the blue box in the screenshot. in case you are confused by the code snippet i posted earlier: it is missing the debug messagebox and the rearranged static strings etc... it is not up to date anymore.
TI-994A wrote:All corresponding modules must be compiled on the same architecture (32bit or 64bit)
naturally. everything is 32bit right now.
TI-994A wrote:and must also be configured for the same character set; UNICODE for your requirements
that is not possible. I need to translate at some point, as my target program expects its strings to be UTF-8 and sends out strings as UTF-8.
PB 5.24 LTS x86 has the "Unicode" (I suppose UTF-16) checkbox set in the compiler options. So PB "translates" the input string from UTF-8 using PeekS(). This part works.
I guess the returned string (PB to MSVS) is still Unicode UTF-16 and not UTF-8, as I need it to be. So I suppose my final question is this, can I return a UTF-8 string instead of an UTF-16 string from the PB DLL? or do I have to take a detour and e.g. send the memory address where i PokeS()'ed the UTF-8 string?

thanks for all your efforts.
User avatar
TI-994A
Addict
Addict
Posts: 2741
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: using PB-made dll in MSVSC++12/13 project - unicode prob

Post by TI-994A »

broozar wrote:PB does display everything correctly in its own message box...
We've been trying to pass wide characters (UNICODE) using a standard character pointer (char*). The oversight on my part is that I've been testing with only ASCII characters; which works, thus not exposing the error that you're facing.

Try these changes:

1. In the PureBasic DLL (compiled as a 32bit UNICODE DLL):

Code: Select all

ProcedureDLL.s MyFunction(receivedString.s)
  Static returnString.s
  returnString = "Received: " + receivedString   ;no PeekS() required!
  MessageRequester("PureBasic Message Box: ", returnString, 0)
  ProcedureReturn returnString
EndProcedure
2. In the VS2013 header (both char* changed to wchar_t*):

Code: Select all

#pragma comment (lib, "DLL Example")
extern "C" __declspec(dllimport) wchar_t* _stdcall MyFunction(wchar_t* filePath);
3. In the VS2013 C/C++ source (compiled as 32bit with UNICODE character set):

Code: Select all

//note the [L] casts before the constant strings
wchar_t* cStr = L"Нык ан чонэт оффэндйт мальюизчыт";   //sample cyrillic string
wchar_t* response = MyFunction(cStr);
MessageBox(NULL, LPCWSTR(response), L"VS2013 Message Box:", MB_OK);
Hope it works! :lol:
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
broozar
User
User
Posts: 61
Joined: Sat May 08, 2010 11:21 pm
Location: Berlin, Germany

Re: using PB-made dll in MSVSC++12/13 project - unicode prob

Post by broozar »

faaantastic! it works now. for future reference, here's the solution I ended up with from back to back:

1. SETTING
- PB compiles to unicode UTF-16 DLL
- program using the DLL accepts only UTF-8, both input and return

2. STRINGS TO PB
- utf-8 input needs to be converted: use PeekS() with the #PB_UTF8 flag

3. STRINGS OUT OF PB
- return strings are UTF-16, will need to be converted in 5.

4. MSVS C++ HEADER
- use wchar_t* instead of const char* to receive the strings from 3. correctly

Code: Select all

extern "C" {
    // other declarations here... then:
    __declspec(dllimport) wchar_t* __stdcall pg_translate (const char* LANGCODE, const char* CODESTRING, int bLC);
}
5. MSVS UTF-16 TO UTF-8

Code: Select all

wchar_t* trans = pg_translate(lc, pc, bl); // pg_translate being the PB DLL procedure
char buf[256]; // temp buffer
WideCharToMultiByte(CP_UTF8, 0, trans, -1, buf, _countof(buf), NULL, NULL); // conversion to UTF-8
const char* t2 = (const char*) &buf; // cast to const char*
// now t2 can be used in the UTF-8 application
thanks for the help everybody!
Fred
Administrator
Administrator
Posts: 18234
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: using PB-made dll in MSVSC++12/13 project - unicode prob

Post by Fred »

Instead of returning a string, you could also returns a memory buffer in the right format, so all the work is done in the DLL:

Code: Select all

ProcedureDLL MyUTF8StringReturn(receivedString.s)
  Static *String
  If *String ; Free the previous string
    Debug "free the previous string"
    FreeMemory(*String)
  EndIf

  *String = AllocateMemory(StringByteLength(receivedString, #PB_UTF8)+1)
  PokeS(*String, receivedString, -1, #PB_UTF8)
  ProcedureReturn *String 
EndProcedure

Debug PeekS(MyUTF8StringReturn("Test"+Random(1000000)), -1, #PB_UTF8)
Debug PeekS(MyUTF8StringReturn("Test"+Random(1000000)), -1, #PB_UTF8)
Debug PeekS(MyUTF8StringReturn("Test"+Random(1000000)), -1, #PB_UTF8)
Debug PeekS(MyUTF8StringReturn("Test"+Random(1000000)), -1, #PB_UTF8)
broozar
User
User
Posts: 61
Joined: Sat May 08, 2010 11:21 pm
Location: Berlin, Germany

Re: using PB-made dll in MSVSC++12/13 project - unicode prob

Post by broozar »

Fred wrote:all the work is done in the DLL
that sounds even better! how would the changes on the c++ side look like?
- does MyUTF8StringReturn return a standard int?
- if so, just cast to char*?

i did that and it seems to work, I just thought i'd ask.
Post Reply