PDA

View Full Version : Problems linking multiple dependent libraries involving XML schema and Cstrings



aknight3
23rd August 2015, 19:49
I'm attempting to incorporate an SDK into my project and wanted to use Qt for the gui development. According to SDK documentation: " Our VC++ SDK requires the Visual C++ 2010 Redistributable package from Microsoft and the Code Synthesis XSD compiler and libraries from Code Synthesis." So first i installed XSD(version 3.3) and added the various necessary dependencies in visual studio 10 and successfully built the examples. I then installed the Qt 5.5 plugin(also later installed the Qt5.5_msvc10 build...both lead to the same error).

The problem i keep encountering is that while I get a successful build just using the functions and classes from the SDK, any attempt to do anything with it(access elements of a std::list, for example) produces the following error:
LNK2019: unresolved external symbol "__declspec(dllimport) public: class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > > __thiscall CAccount::GetAccountId(void)" (__imp_?GetAccountId@CAccount@@QAE?AV?$CStringT@_W V?$StrTraitMFC_DLL@_WV?$ChTraitsCRT@_W@ATL@@@@@ATL @@XZ) referenced in function "private: void __thiscall MainWindow::on_pushButton_2_clicked(void)" (?on_pushButton_2_clicked@MainWindow@@AAEXXZ)

For Example:


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtCore>
#include "ladderwindow.h"
#include "OAuth/OAuthSDK.h"
#include "Accounts/AccountSDK.h"
#include "Market/MarketSDK.h"
#include "Order/OrderSDK.h"
#include <QtNetwork>



namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:
void on_pushButton_2_clicked();

private:
CAccountSDK *acc;
AccountList alist;

};

#endif // MAINWINDOW_H

//Mainwindow.cpp//
#include "mainwindow.h"
#include "ladderwindow.h"
#include "ui_mainwindow.h"

#include <QCoreApplication>
#include <QString>

#include <OAuth/OAuthSDK.h>
#include <Accounts/AccountSDK.h>
#include <Market/MarketSDK.h>
#include <Order/OrderSDK.h>

#include <QUrl>
#include <QUrlQuery>
#include <QWebElement>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{...}

void MainWindow::on_pushButton_2_clicked()
{
try {
AuthCode = ui->lineEdit->text();
mAuth->GetAccessToken(*client,AuthCode.toStdString());
try {
acc = new CAccountSDK(*client);

alist = acc->GetAccountList(); //Builds, application output window streams a XML of the response

std::wstring mangledstringtest(CString("WTF"));
ui->textBrowser->append(QString::fromStdWString(mangledstringtest)) ;

// This and all other attempts to do anything with alist fails to compile
foreach(CAccount i, alist)
{
//ui->textBrowser->append(QString::fromStdString(i.GetAccountId()));
//USES_CONVERSION
ui->textBrowser->append(QString::fromWCharArray((i.GetAccountId().G etBuffer())));
//std::wstring mangledstring(CString(i.GetAccountId()));
//ui->textBrowser->append(QString::fromStdWString(mangledstring));
}
} catch (...) {}
ladder = new ladderwindow(this);
ladder->show();
}
catch (...) {}
}



Since the calls I make are from the libraries from the SDK, my thought is that perhaps a) i haven't properly specified the paths to the necessary dlls from the codesynthesis xsd installation or b) i need to make some modifications and/or includes of various string related header files included with the SDK.
Heres a portion of my .pro



QT += core gui
QT += network
QT += webkitwidgets network widgets

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Etrader
TEMPLATE = app

#PRECOMPILED_HEADER = stdafx.h

SOURCES += main.cpp\
automain.cpp \
mainwindow.cpp \
ladderwindow.cpp

HEADERS += automain.h \
OAuth/OAuthSDK.h \
Accounts/AccountSDK.h \
Market/MarketSDK.h \
Order/OrderSDK.h \
mainwindow.h \
ladderwindow.h

FORMS += automain.ui \
mainwindow.ui \
ladderwindow.ui

DEFINES += _AFXDLL

INCLUDEPATH += "C:/ProgramFiles(x86)/CodeSynthesisXSD3.3/xerces-c-3.1.1/src"
INCLUDEPATH += "C:/ProgramFiles(x86)/CodeSynthesisXSD3.3/bin"
INCLUDEPATH += "C:/ProgramFiles(x86)/CodeSynthesisXSD3.3/include"

win32: LIBS += -L$$PWD/../../Program Files (x86)/CodeSynthesis XSD 3.3/lib/vc-10.0/ -lxerces-c_3

INCLUDEPATH += $$PWD/../../Program Files (x86)/CodeSynthesis XSD 3.3/lib/vc-10.0
DEPENDPATH += $$PWD/../../Program Files (x86)/CodeSynthesis XSD 3.3/lib/vc-10.0

win32: LIBS += -L$$PWD/../../Program Files (x86)/CodeSynthesis XSD 3.3/lib/vc-10.0/ -lxerces-c_3D

INCLUDEPATH += $$PWD/../../Program Files (x86)/CodeSynthesis XSD 3.3/lib/vc-10.0
#DEPENDPATH += $$PWD/../../Program Files (x86)/CodeSynthesis XSD 3.3/lib/vc-10.0


#1 of 5 SDK libs...
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../build-Etrader-Desktop_Qt_5_5_0_MSVC2010_32bit-Debug/release/ -lETCommon
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../build-Etrader-Desktop_Qt_5_5_0_MSVC2010_32bit-Debug/debug/ -lETCommon
else:unix:!macx: LIBS += -L$$PWD/../build-Etrader-Desktop_Qt_5_5_0_MSVC2010_32bit-Debug/ -lETCommon

INCLUDEPATH += $$PWD/../build-Etrader-Desktop_Qt_5_5_0_MSVC2010_32bit-Debug/debug
DEPENDPATH += $$PWD/../build-Etrader-Desktop_Qt_5_5_0_MSVC2010_32bit-Debug/debug

win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/../build-Etrader-Desktop_Qt_5_5_0_MSVC2010_32bit-Debug/release/libETCommon.a
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/../build-Etrader-Desktop_Qt_5_5_0_MSVC2010_32bit-Debug/debug/libETCommon.a
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/../build-Etrader-Desktop_Qt_5_5_0_MSVC2010_32bit-Debug/release/ETCommon.lib
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/../build-Etrader-Desktop_Qt_5_5_0_MSVC2010_32bit-Debug/debug/ETCommon.lib
else:unix:!macx: PRE_TARGETDEPS += $$PWD/../build-Etrader-Desktop_Qt_5_5_0_MSVC2010_32bit-Debug/libETCommon.a


And here potentially relevant portions of the stdafx and headers related to CStringT that seem to be a problem:



//stdafx.h
#pragma once

#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN
#endif
typedef std::basic_string<TCHAR> tstring;
#define SIZEOF(x) (sizeof(x)/sizeof(*x))

#define COMMON_LIBRARY_EXPORT

#include "common/Common/StringUtil.h"
#include "common/Common/Base64Coder.h"


//StringUtil.h
#ifndef _STRINGUTIL_H_INCLUDED_
#define _STRINGUTIL_H_INCLUDED_
#include "CommonDefs.h"
#include <stdlib.h>
#include <string>
#include <iostream>
#include <stdlib.h>
#include <string>

#include "atlbase.h"
#include "atlstr.h"
#include "comutil.h"

using namespace std;

#ifdef _UNICODE
#define TCHARToUTF8 WideToUTF8
#define UTF8ToTCHAR UTF8ToWide
#define TCHARToWide
#define WideToTCHAR
#define TCHARToMB WideToMB
#define MBToTCHAR MBToWide
#else
#define TCHARToUTF8 ANSIToUTF8
#define UTF8ToTCHAR UTF8ToANSI
#define TCHARToWide MBToWide
#define WideToTCHAR WideToMB
#define TCHARToMB
#define MBToTCHAR
#endif

class CStringUtil
{
public:
CStringUtil(void);
virtual ~CStringUtil(void);

void Split(const tstring& str, std::vector<tstring>& out, TCHAR sep, bool includeEmpty);
tstring GetWord(const tstring& str, unsigned index, bool getRest = false);

inline bool Compare(const tstring& one, const tstring& two, bool caseSensitive)
{
return caseSensitive ? (one == two) : (_tcsicmp(one.c_str(), two.c_str()) == 0);
};
};

#endif//_STRINGUTIL_H_INCLUDED_

//CBase64Coder.h
#pragma once

#ifdef _AFXDLL
#include <afx.h>
typedef CString String;
#else
#include <windows.h>
#include <string>
typedef std::string String;
#endif

#ifndef CBase64Coder_HEADER
#define CBase64Coder_HEADER
#endif

class CBase64Coder
{
private:
// Internal bucket class.
class TempBucket
{
public:
BYTE nData[4];
BYTE nSize;
void Clear() { ::ZeroMemory(nData, 4); nSize = 0; };
};

PBYTE m_pDBuffer;
PBYTE m_pEBuffer;
DWORD m_nDBufLen;
DWORD m_nEBufLen;
DWORD m_nDDataLen;
DWORD m_nEDataLen;

public:
CBase64Coder();
virtual ~CBase64Coder();

public:
virtual void Encode(const PBYTE, DWORD);
virtual void Decode(const PBYTE, DWORD);
virtual void Encode(LPCSTR sMessage);
virtual void Decode(LPCSTR sMessage);

virtual LPCSTR DecodedMessage() const;
virtual LPCSTR EncodedMessage() const;

virtual void AllocEncode(DWORD);
virtual void AllocDecode(DWORD);
virtual void SetEncodeBuffer(const PBYTE pBuffer, DWORD nBufLen);
virtual void SetDecodeBuffer(const PBYTE pBuffer, DWORD nBufLen);

protected:
virtual void _EncodeToBuffer(const TempBucket &Decode, PBYTE pBuffer);
virtual ULONG _DecodeToBuffer(const TempBucket &Decode, PBYTE pBuffer);
virtual void _EncodeRaw(TempBucket &, const TempBucket &);
virtual void _DecodeRaw(TempBucket &, const TempBucket &);
virtual BOOL _IsBadMimeChar(BYTE);

static char m_DecodeTable[256];
static BOOL m_Init;
void _Init();

};



I've tried switching around the order in which ive added the various Libraries as well changing between static and dynamic with no luck. Ive searched and tried a whole bunch of different means of intermediate conversions to see if i could convert the cstring into something i could then convert to a Qstring but anything i've tried still produces the linker error. I've been stuck on this for about 4 days now and I'm out of ideas...Could someone point me in the right direction?

ChrisW67
23rd August 2015, 21:35
It looks like your unnamed SDK is Microsoft MFC-based. Would that be correct?

aknight3
23rd August 2015, 21:57
Hi, thanks for the reply. Yes, as best I can tell the ETrade C++ https://developer.etrade.com/ctnt/dev-portal/getContent?contentUri=V0_Code-SDKGuides-VC appears to be MFC-based

initial build after adding all the libraries produced:
C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]

which prompted me to add the DEFINES += _AFXDLL