![]() |
|
| |
![]() |
#1 |
高级会员
注册日期: 06-11
帖子: 14579
精华: 1
现金: 224494 标准币
资产: 234494 标准币
![]() |
![]() link error with dd 2.2.0 and wchar_t as built in type
link error with dd 2.2.0 and wchar_t as built in type hi, i was trying to integrate with dd libs 2.2.0 for vc8. when i turn on "treat whcar_t as built-in type", i get the following linking error regarding odcharmapper::codepagetounicode(). debug target: code: 1>utils.obj : error lnk2019: unresolved external symbol "public: static enum odresult __cdecl odcharmapper::codepagetounicode(wchar_t,enum odcodepageid,wchar_t &)" (?codepagetounicode@odcharmapper@@sa?aw4odresult@@_ww4odcodepageid@@aa_w@z) referenced in function "public: static int __cdecl utils::appendmultibyteasunicode2list<class std::vector<unsigned short,class std::allocator<unsigned short> > >(unsigned short,int,class std::vector<unsigned short,class std::allocator<unsigned short> > &)" (??$appendmultibyteasunicode2list@v?$vector@gv?$allocator@g@std@@@std@@@utils@@sahghaav?$vector@gv?$allocator@g@std@@@std@@@z) 1>..\..\..\..\..\... : fatal error lnk1120: 1 unresolved externals release target: code: 1>utils.obj : error lnk2019: unresolved external symbol "public: static enum odresult __cdecl odcharmapper::codepagetounicode(wchar_t,enum odcodepageid,wchar_t &)" (?codepagetounicode@odcharmapper@@sa?aw4odresult@@_ww4odcodepageid@@aa_w@z) referenced in function "public: static int __cdecl utils::appendmultibyteasunicode2list<class ai::unicodestring>(unsigned short,int,class ai::unicodestring &)" (??$appendmultibyteasunicode2list@vunicodestring@ai@@@utils@@sahghaavunicodestring@ai@@@z) 1>..\..\..\..\..\... : fatal error lnk1120: 1 unresolved externals but when i turn off "treat whcar_t as built-in type", the project builds successfully. any ideas? regards, varun indeed, there are some interfaces, that use wchar_t, instead of odchar. this is a bug, and it will be fixed. as a workaround, you may fix the header manually, and try again. (fix: wchar_t -> odchar) vladimir strange happenings with text import hi, with 2.1.0, the attached file produced the following sequence with oddbtextiterator in my textproc(): {0x65b0, 0x30d0, 0x30fc, 0x30b8, 0x30e7, 0x30f3} with 2.2.0, the sequence generated with oddbtextiterator in my textproc() is now: {0x9056, 0x836f, 0x815b, 0x8357, 0x8387, 0x8393} i could reproduce the same difference in odvectorizeex of the two versions by introducing oddbtextiterator in their odgiconveyorgeometrydumper::textproc(). what is it that has changed between these two revisions? i am using vc8 static libs and my usage is as follows: code: void exgssimpledevice::textproc(const odgepoint3d& position, const odgevector3d& u, const odgevector3d& v, const odchar* msg, odint32 length, bool raw, const odgitextstyle* ptextstyle, const odgevector3d* pextrusion) { ... oddbtextiteratorptr textiter = oddbtextiterator::createobject(msg, length, raw, ptextstyle->getcodepage(), ptextstyle); oduint16 nextchar = textiter->nextchar(); if (nextchar) { ... } ... } attached files (49.6 kb, 4 views) regards, varun also forgot to mention: i tried changing the header (wchar_t > odchar) and the linking succeeded. but our integration of the new libs is struck pending resolution of the text issue detailed above. regards, varun last edited by varunsnair; 17th december 2006 at 04:40 amfff">. quote: originally posted by varunsnair with 2.1.0, the attached file produced the following sequence with oddbtextiterator in my textproc(): {0x65b0, 0x30d0, 0x30fc, 0x30b8, 0x30e7, 0x30f3} with 2.2.0, the sequence generated with oddbtextiterator in my textproc() is now: {0x9056, 0x836f, 0x815b, 0x8357, 0x8387, 0x8393} i could reproduce the same difference in odvectorizeex of the two versions by introducing oddbtextiterator in their odgiconveyorgeometrydumper::textproc(). what is it that has changed between these two revisions? hi, oddbtextiterator::nextchar() returns symbols in font coding. it is mbcb for big font. so you are getting {0x9056, 0x836f, 0x815b, 0x8357, 0x8387, 0x8393}. acad also draws this mtext using big font (extfont.shx). best regards, sergey z. hi sergey, how then do we go about getting the unicode values out of the text. based on the behavior of nextchar() in 2.1.0, we had devised the following method to get the information: code: ... bool supportsunicode = ((ptextstyle->getfont()->getflags() & (kunifont10 | ktruetype)) != 0); oddbtextiteratorptr textiter = oddbtextiterator::createobject(msg, length, raw, ptextstyle->getcodepage(), ptextstyle); odcharacterproperties oldcharprops; // we'll be mapping only underline using this for now std::vector<oduint16> umsg; oduint16nextchar = textiter->nextchar(); if (nextchar) { odcharacterproperties newcharprops; oldcharprops = textiter->currproperties(); if ((oldcharprops.binbigfont || !supportsunicode) && textiter->currpos() - msg >= kautocadmultibytesequencelength && utils::isvalidautocadmultibytesequence(textiter->currpos() - kautocadmultibytesequencelength)) { utils::appendmultibyteasunicode2list(nextchar, utils::gethexcodefromchar(*(textiter->currpos() - kautocadmultibytesequencelength + kcodepageoffsetinautocadmultibytesequence)), umsg); } else { umsg.push_back(nextchar); } for (nextchar = textiter->nextchar(); (nextchar); nextchar = textiter->nextchar()) { int charsadded = 1; newcharprops = textiter->currproperties(); if ((newcharprops.binbigfont || !supportsunicode) && textiter->currpos() - msg >= kautocadmultibytesequencelength && utils::isvalidautocadmultibytesequence(textiter->currpos() - kautocadmultibytesequencelength)) { charsadded = utils::appendmultibyteasunicode2list(nextchar, utils::gethexcodefromchar(*(textiter->currpos() - kautocadmultibytesequencelength + kcodepageoffsetinautocadmultibytesequence)), umsg); } else { umsg.push_back(nextchar); } if (oldcharprops.bunderlined != newcharprops.bunderlined) { ... // add all but the last character to our text entity ... oldcharprops = newcharprops; // reinitialize // discard all but the recently added characters umsg.erase(umsg.begin(), umsg.end() - charsadded); } } } if (!umsg.empty()) { // last run ... // add all remaining characters to our text entity } ... implementation of utility methods used in above code are as follows: code: bool utils::isvalidhexchar(const odchar& hexchar) { return ((hexchar >= '0' && hexchar <= '9') || (hexchar >= 'a' && hexchar <= 'f') || (hexchar >= 'a' && hexchar <= 'f')); } odchar utils::gethexcodefromchar(const odchar& hexchar) { if (hexchar >= '0' && hexchar <= '9') { return (hexchar - '0'); } else if (hexchar >= 'a' && hexchar <= 'f') { return (hexchar - 'a' + 0xa); } else if (hexchar >= 'a' && hexchar <= 'f') { return (hexchar - 'a' + 0xa); } return (-1); } bool utils::isvalidautocadmultibytesequence(const odchar *str) { return (*str == '\\' && (*(str + 1) == 'm' || *(str + 1) == 'm') && *(str + 2) == '+' && (gethexcodefromchar(*(str + 3)) > 0 && gethexcodefromchar(*(str + 3)) <= 5) && isvalidhexchar(*(str + 4)) && isvalidhexchar(*(str + 5)) && isvalidhexchar(*(str + 6)) && isvalidhexchar(*(str + 7))); } odcodepageid utils: ![]() { odcodepageid codepageid; switch (codepagenum) { case 1: // (932) japanese (shift-jis) codepageid = cp_ansi_932; break; case 2: // (950) traditional chinese (big 5) codepageid = cp_ansi_950; break; case 3: // (949) wansung (ks c-5601-1987) codepageid = cp_ansi_949; break; case 4: // (1361) johab (ks c-5601-1992) codepageid = cp_ansi_1361; break; case 5: // (936) simplified chinese (gb 2312-80) codepageid = cp_ansi_936; break; default: codepageid = cp_ansi_932; break; } return codepageid; } // valid values of codepagenum are the values of 'n' in the autocad multibyte sequences '\m+nxxxx' template <typename listt> int utils::appendmultibyteasunicode2list(const oduint16 multibyte, const int codepagenum, listt& list) { int oldlistsize = list.size(); odcodepageid codepageid = odcodepagenum2odcodepageid(codepagenum); odchar convertedchar; odresult result = odcharmapper::codepagetounicode(multibyte, codepageid, convertedchar); if (result == eok) { list.push_back(convertedchar); } else { // append the \m+nxxxx sequence list.push_back('\\'); list.push_back('m'); list.push_back('+'); list.push_back(getcharfromhexcode(codepagenum)); list.push_back(getcharfromhexcode((multibyte & 0xf000) >> 12)); list.push_back(getcharfromhexcode((multibyte & 0x0f00) >> 8)); list.push_back(getcharfromhexcode((multibyte & 0x00f0) >> 4)); list.push_back(getcharfromhexcode(multibyte & 0x000f)); } int charsadded = list.size() - oldlistsize; return charsadded; } i see that you guys have introduced similar utilities in odcharconvertor.h. however, as you can see, all this handling only works if we have a \m+nxxxx form text and nextchar() returns us the converted big font char for this sequence. for the text in the attached file, binbigfont comes false for us. we really only want the original string passed in to textproc(), which is what we were getting in 2.1.0. with 2.2.0, how do we handle the conversion which seems to be taking place for nextchar()? regards, varun hi varum, start from version 2.0.0 textproc() gets message as unicode string. but possible such situation then string contents code like "\m+nxxxx" (for example: there is no way to convert to unicode because codepage map is absent). quote: originally posted by varunsnair however, as you can see, all this handling only works if we have a \m+nxxxx form text and nextchar() returns us the converted big font char for this sequence. in non unicode version string may has mbcb code instead of m+nxxxx ( for example dwgcodepage is in accordance n). best regards, sergey z. i don't follow sergey. in this case, the msg parameter passed to textproc() is the same in 2.2.0 as it was in 2.1.0. the special handling was only put in place to deal with \m+nxxxx sequences which nextchar() failed to convert to unicode, based on the following comment in the header: code: /** description: returns the next character in the string associated with this textiterator object. remarks: the returned character will be a unicode character except when the binbigfont flag is set in the currproperties() value. in this case, the returned character will be mbcs, corresponding to a \m+nxxxx character in the original string. */ virtual oduint16 nextchar() = 0; but in 2.2.0, nextchar() is actually converting the unicode string (msg passed into textproc()), into mbcb. how would we ever know that such a conversion has taken place? do we just stop using nextchar() and start parsing the msg parameter? in that case how do we access the character properties which oddbtextiterator provides us? regards, varun hi varum, the description has some mistake. the original string has \m+nxxxx in case conversion to unicode is impossibly. quote: originally posted by varunsnair do we just stop using nextchar() and start parsing the msg parameter? in that case how do we access the character properties which oddbtextiterator provides us? the oddbtextiterator was designed for specific purpose (text redering) and it is connected with font mainly (there are some shx font with multy byte coding.). i think you need parsing source string for your task. note switch for underline text is "\u"("\u"). best regards, sergey z. so sergey, if i just change my code in the colored portions below, you think the problem would be resolved? code: ... bool supportsunicode = ((ptextstyle->getfont()->getflags() & (kunifont10 | ktruetype)) != 0); oddbtextiteratorptr textiter = oddbtextiterator::createobject(msg, length, raw, ptextstyle->getcodepage(), ptextstyle); odcharacterproperties oldcharprops; // we'll be mapping only underline using this for now std::vector<oduint16> umsg; oduint16nextchar = textiter->nextchar(); if (nextchar) { odcharacterproperties newcharprops; oldcharprops = textiter->currproperties(); if ((oldcharprops.binbigfont || !supportsunicode) && textiter->currpos() - msg >= kautocadmultibytesequencelength && utils::isvalidautocadmultibytesequence(textiter->currpos() - kautocadmultibytesequencelength)) { utils::appendmultibyteasunicode2list(nextchar, utils::gethexcodefromchar(*(textiter->currpos() - kautocadmultibytesequencelength + kcodepageoffsetinautocadmultibytesequence)), umsg); } else { umsg.push_back(*(textiter->currpos() - 1)fff">); } for (nextchar = textiter->nextchar(); (nextchar); nextchar = textiter->nextchar()) { int charsadded = 1; newcharprops = textiter->currproperties(); if ((newcharprops.binbigfont || !supportsunicode) && textiter->currpos() - msg >= kautocadmultibytesequencelength && utils::isvalidautocadmultibytesequence(textiter->currpos() - kautocadmultibytesequencelength)) { charsadded = utils::appendmultibyteasunicode2list(nextchar, utils::gethexcodefromchar(*(textiter->currpos() - kautocadmultibytesequencelength + kcodepageoffsetinautocadmultibytesequence)), umsg); } else { umsg.push_back(*(textiter->currpos() - 1)fff">); } if (oldcharprops.bunderlined != newcharprops.bunderlined) { ... // add all but the last character to our text entity ... oldcharprops = newcharprops; // reinitialize // discard all but the recently added characters umsg.erase(umsg.begin(), umsg.end() - charsadded); } } } if (!umsg.empty()) { // last run ... // add all remaining characters to our text entity } ... regards, varun hi varum, i think it will work with braw parametr textproc() equal true. otherwise problem is left with special symbols which text may contents( "%%d" - degree, "%%p" - plus-minus, "%%c" - diameter and "%%xxx" where xxx - code symbol). best regards, sergey z. thanks sergey. the approach did fail when raw == false. in this case, we're now checking and handling the 4 special sequences (%%c, %%p, %%d and %%nnn), separately. anything else we should be checking for? tia. regards, varun hi varum, the symbols %%c, %%p, %%d are no case sensitive. and i forgot percentage "%%%". the switches underline (%%u) and overline (%%o) are processed in nextchar() and currpos() is shifted accordingly. best regards, sergey z. hi sergey, '%%%' would work fine with the default case of "*(textiter->currpos() - 1)" as it has '%' as the last char. not case-senstive, is not an issue, i'll check for both upper and lower case alphabets in these. yesterday, i had thought about checking this out, but somehow it slipped my mind. thanks for reminding me! according to our logic, underline and overline sequences will never be at -1 position with respect to currpos() after nextchar(). so we are not handling them. just confirming, 'n' in '%%nnn' sequence stands for a decimal digit (values: 0 - 9). am i correct? regards, varun quote: originally posted by varunsnair '%%%' would work fine with the default case of "*(textiter->currpos() - 1)" as it has '%' as the last char. according to our logic, underline and overline sequences will never be at -1 position with respect to currpos() after nextchar(). so we are not handling them. you are right. quote: originally posted by varunsnair just confirming, 'n' in '%%nnn' sequence stands for a decimal digit (values: 0 - 9). am i correct? yes! it is a decimal digit. best regards, sergey z. |
![]() |
![]() |
GDT自动化论坛(仅游客可见) |