我在VS2005中创建了一个小型CLR库(MyClient),将线程集成到现有的C ++应用程序中(也用VS2005编写)。当我构建项目时会出现以下错误:
1>PSR_CRSDlg.obj : error LNK2019: unresolved external symbol "public: static void __cdecl MyClient::StartClientThread(void)" (?StartClientThread@MyClient@@SAXXZ) referenced in function "public: void __thiscall CPSR_CRSDlg::OnBnClickedInit2(void)" (?OnBnClickedInit2@CPSR_CRSDlg@@QAEXXZ)
1>PSR_CRSDlg.obj : error LNK2019: unresolved external symbol "public: static void __cdecl MyClient::SendJointValues(double *)" (?SendJointValues@MyClient@@SAXPAN@Z) referenced in function "public: void __thiscall CPSR_CRSDlg::OnTimer(unsigned int)" (?OnTimer@CPSR_CRSDlg@@QAEXI@Z)
1>PSR_CRSDlg.obj : error LNK2019: unresolved external symbol "public: static void __cdecl MyClient::StopConnection(void)" (?StopConnection@MyClient@@SAXXZ) referenced in function "public: void __thiscall CPSR_CRSDlg::OnBnClickedMovepenall(void)" (?OnBnClickedMovepenall@CPSR_CRSDlg@@QAEXXZ)
1>D:\Desktop\PSR\Software\Source - June 21\PSR_CRS_SVN - Copy (2)\Debug\PSR_CRS.exe : fatal error LNK1120: 3 unresolved externals
我是C ++和OOP的新手,但过去几周一直在不断进行。这是我的.h文件:
using namespace std;
class MyClient
{
public:
static char* createMsg(string s);
static char* parseJSON(double j1, double j2, double j3, double j4, double j5, double j6);
static void StartConnection();
static void StartClientThread();
static void StopConnection();
static void SendJointValues(double *joints);
};
我的.cpp文件只是将函数实例化为char * MyClient :: createMsg(string s)等,所以我不认为这是问题所在。我还浏览了大部分链接here并进行了大量搜索,以确保我的库全部存在,没有循环的lib依赖,库顺序等。在我的整个解决方案中的3个项目中,2个使用“没有公共语言运行时支持”但我的客户端库使用“公共语言运行时支持”,这是库之间的一个区别。
有没有人想过为什么会出现这些错误?
完整客户端库:
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include "stdafx.h"
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <iostream>
#include <typeinfo>
#include <sstream>
#include "Client.h"
using namespace std;
using namespace System;
using namespace System::Threading;
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define DEFAULT_BUFLEN 4096
#define DEFAULT_PORT "9001"
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
SOCKET ConnectSocket;
char* MyClient::createMsg(string s) {
char *a = new char[s.size() + 1];
a[s.size()] = 0;
memcpy(a, s.c_str(), s.size());
return a;
}
char* MyClient::parseJSON(double j1, double j2, double j3, double j4, double j5, double j6)
{
ostringstream oss;
oss << j1 << ',' << j2 << ',' << j3 << ',' << j4 << ',' << j5 << ',' << j6;
string joints = oss.str();
return createMsg(joints);
}
void MyClient::StartConnection()
{
//printf("Connection Starting... \n");
WSADATA wsaData;
ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
int argc = 2;
// Validate the parameters
if (argc != 2) {
printf("usage: %s server-name\n", "client");
return;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
//iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
iResult = getaddrinfo("localhost", DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return;
}
return;
}
void MyClient::StopConnection(){
closesocket(ConnectSocket);
WSACleanup();
return;
}
void MyClient::SendJointValues(double *joints){
char *j;
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
j = parseJSON(joints[0],joints[1],joints[2],joints[3], \
joints[4],joints[5]);
int x = send(ConnectSocket, j, strlen(j), 0);
//iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
}
void MyClient::StartClientThread()
{
Thread^ cln;
ThreadStart ^ClientThread = gcnew ThreadStart(&MyClient::StartConnection);
cln = gcnew Thread(ClientThread);
cln->IsBackground = true;
cln->Start();
}
编辑:当我创建虚拟应用程序与我正在尝试集成的应用程序相同的设置时,没有发生这些错误,这就是为什么我不确定发生了什么变化或如何解决错误。
答案 0 :(得分:0)
我想也许您在EXE中包含了库中的头文件。
在C ++ / CLI中编写库时,它使用.Net机制导出类。你不需要一个头文件来声明这个类,.Net元数据可以解决这个问题。
只需确保您的EXE已将库添加为.Net参考,然后继续使用库类。
答案 1 :(得分:0)
所以我不确定这个特定错误的确切原因是什么,但总的来说我发现由于原始应用程序使用/ MTd运行时库和使用我的新库而遇到了很多麻烦/ MD