本文主要總結將類生成dll並且調用中遇到的坑和操作。平時打包成一個類的好處在於內部可以有多個成員函數供以調用,且成員變量也可以共用。如果平時想用到多個函數打包成的dll,那一個個封裝會很繁瑣,且多個函數間可能會用到共用的變量,**分開封裝,相應變量將得不到及時的更新。因爲每次主線程進入dll的時候,相應變量是不共享內存的,dll中操作的是變量的拷貝版,而不是變量本身。**所以今後儘量將多個函數統一成一個類內的成員函數最好,坑也相對來說最少。
類的封裝
類的封裝,在VS中生成:
1…h文件聲明類及內部成員
2…cpp文件定義函數及變量
.h文件包含內容
#pragma once
#ifndef __COMANGLE_H__
#define __COMANGLE_H__
#include "windows.h"
#include <stdio.h>
#include <tchar.h>
//#ifdef _WIN32
//#ifdef CCA_API //這個在哪裏定義了?
#define CCA_API __declspec(dllexport)
//#else
//#define CCA_API __declspec(dllimport)
//#endif
//#else
//#define CCA_API __attribute__ ((visibility("default")))
//#endif
#ifndef JY901_h
#define JY901_h
#define SAVE 0x00
#define CALSW 0x01
#define RSW 0x02
#define RRATE 0x03
#define BAUD 0x04
#define AXOFFSET 0x05
#define AYOFFSET 0x06
#define AZOFFSET 0x07
#define GXOFFSET 0x08
#define GYOFFSET 0x09
#define GZOFFSET 0x0a
#define HXOFFSET 0x0b
#define HYOFFSET 0x0c
#define HZOFFSET 0x0d
#define D0MODE 0x0e
#define D1MODE 0x0f
#define D2MODE 0x10
#define D3MODE 0x11
#define D0PWMH 0x12
#define D1PWMH 0x13
#define D2PWMH 0x14
#define D3PWMH 0x15
#define D0PWMT 0x16
#define D1PWMT 0x17
#define D2PWMT 0x18
#define D3PWMT 0x19
#define IICADDR 0x1a
#define LEDOFF 0x1b
#define GPSBAUD 0x1c
#define YYMM 0x30
#define DDHH 0x31
#define MMSS 0x32
#define MS 0x33
#define AX 0x34
#define AY 0x35
#define AZ 0x36
#define GX 0x37
#define GY 0x38
#define GZ 0x39
#define HX 0x3a
#define HY 0x3b
#define HZ 0x3c
#define Roll 0x3d
#define Pitch 0x3e
#define Yaw 0x3f
#define TEMP 0x40
#define D0Status 0x41
#define D1Status 0x42
#define D2Status 0x43
#define D3Status 0x44
#define PressureL 0x45
#define PressureH 0x46
#define HeightL 0x47
#define HeightH 0x48
#define LonL 0x49
#define LonH 0x4a
#define LatL 0x4b
#define LatH 0x4c
#define GPSHeight 0x4d
#define GPSYAW 0x4e
#define GPSVL 0x4f
#define GPSVH 0x50
#define DIO_MODE_AIN 0
#define DIO_MODE_DIN 1
#define DIO_MODE_DOH 2
#define DIO_MODE_DOL 3
#define DIO_MODE_DOPWM 4
#define DIO_MODE_GPS 5
#define TOTAL_PORT_NUM 65
#define START_PORT_NUM 0
#define iBufferSize 250
#define UARTBufferLength 2000
#undef SYNCHRONOUS_MODE
struct STime
{
unsigned char ucYear;
unsigned char ucMonth;
unsigned char ucDay;
unsigned char ucHour;
unsigned char ucMinute;
unsigned char ucSecond;
unsigned short usMiliSecond;
};
struct SAcc
{
short a[3];
short T;
};
struct SGyro
{
short w[3];
short T;
};
struct SAngle
{
short Angle[3];
short T;
};
struct SMag
{
short h[3];
short T;
};
struct SDStatus
{
short sDStatus[4];
};
struct SPress
{
long lPressure;
long lAltitude;
};
struct SLonLat
{
long lLon;
long lLat;
};
struct SGPSV
{
short sGPSHeight;
short sGPSYaw;
long lGPSVelocity;
};
class CCA_API CCA
{
public:
struct STime stcTime;
struct SAcc stcAcc;
struct SGyro stcGyro;
struct SAngle stcAngle;
struct SMag stcMag;
struct SDStatus stcDStatus;
struct SPress stcPress;
struct SLonLat stcLonLat;
struct SGPSV stcGPSV;
//static成員變量須在類外定義
static HANDLE hComDev[TOTAL_PORT_NUM];
static unsigned long long ulComMask;
static HANDLE hCOMThread[TOTAL_PORT_NUM];
static OVERLAPPED stcWriteStatus[TOTAL_PORT_NUM];
static OVERLAPPED stcReadStatus[TOTAL_PORT_NUM];
static volatile char chrUARTBuffers[TOTAL_PORT_NUM][UARTBufferLength];
static volatile unsigned long ulUARTBufferStart[TOTAL_PORT_NUM];
static volatile unsigned long ulUARTBufferEnd[UARTBufferLength];
static char chrUARTBufferOutput[1000];
CCA();
void CopeSerialData(unsigned short usLength);
signed char SendUARTMessageLength(const unsigned long ulChannelNo, const char chrMessage[], const unsigned short usLen);
unsigned short CollectUARTData(const unsigned long ulChannelNo);
signed char SetBaundrate(const unsigned long ulPortNo, const unsigned long ulBaundrate);
signed char OpenCOMDevice(const unsigned long ulPortNo, const unsigned long ulBaundrate);
void CloseCOMDevice(void);
//由於後續要進行類型轉換,又是類內成員函數,所以要static修飾
static DWORD WINAPI ReceiveCOMData(PVOID pParam);
~CCA();
};
extern CCA ComAngle;
#endif
#endif
.cpp文件包含
#include "ComAngle.h"
#include "string.h"
CCA::CCA()
{
}
CCA::~CCA()
{
}
HANDLE CCA::hComDev[TOTAL_PORT_NUM] = { NULL }; //初始化時不需要加static
unsigned long long CCA::ulComMask = 0;
HANDLE CCA::hCOMThread[TOTAL_PORT_NUM] = { NULL };
OVERLAPPED CCA::stcWriteStatus[TOTAL_PORT_NUM] = { 0 };
OVERLAPPED CCA::stcReadStatus[TOTAL_PORT_NUM] = { 0 };
volatile char CCA::chrUARTBuffers[TOTAL_PORT_NUM][UARTBufferLength] = { 0 };
volatile unsigned long CCA::ulUARTBufferStart[TOTAL_PORT_NUM] = { 0 };
volatile unsigned long CCA::ulUARTBufferEnd[UARTBufferLength] = { 0 };
char CCA::chrUARTBufferOutput[1000] = { 0 };
CCA ComAngle = CCA();
void CCA::CopeSerialData(unsigned short usLength)
{
static unsigned char chrTemp[2000];
static unsigned char ucRxCnt = 0;
static unsigned short usRxLength = 0;
memcpy(chrTemp, chrUARTBufferOutput, usLength);
usRxLength += usLength;
while (usRxLength >= 11)
{
if (chrTemp[0] != 0x55)
{
usRxLength--;
memcpy(&chrTemp[0], &chrTemp[1], usRxLength);
continue;
}
switch (chrTemp[1])
{
case 0x50: memcpy(&stcTime, &chrTemp[2], 8); break;
case 0x51: memcpy(&stcAcc, &chrTemp[2], 8); break;
case 0x52: memcpy(&stcGyro, &chrTemp[2], 8); break;
case 0x53: memcpy(&stcAngle, &chrTemp[2], 8); break;
case 0x54: memcpy(&stcMag, &chrTemp[2], 8); break;
case 0x55: memcpy(&stcDStatus, &chrTemp[2], 8); break;
case 0x56: memcpy(&stcPress, &chrTemp[2], 8); break;
case 0x57: memcpy(&stcLonLat, &chrTemp[2], 8); break;
case 0x58: memcpy(&stcGPSV, &chrTemp[2], 8); break;
}
usRxLength -= 11;
memcpy(&chrTemp[0], &chrTemp[11], usRxLength);
}
}
signed char CCA::SendUARTMessageLength(const unsigned long ulChannelNo, const char chrSendBuffer[], const unsigned short usLen)
{
DWORD iR;
DWORD dwRes;
DCB dcb;
char chrDataToSend[1000] = { 0 };
memcpy(chrDataToSend, chrSendBuffer, usLen);
memcpy(&chrDataToSend[usLen], chrSendBuffer, usLen);
GetCommState(hComDev[ulChannelNo], &dcb);
dcb.fDtrControl = 0;//DTR = 1;發送
SetCommState(hComDev[ulChannelNo], &dcb);
if (WriteFile(hComDev[ulChannelNo], chrSendBuffer, usLen, &iR, &(stcWriteStatus[ulChannelNo])) || GetLastError() != ERROR_IO_PENDING)
return -1;
dwRes = WaitForSingleObject(stcWriteStatus[ulChannelNo].hEvent, 1000);
Sleep(10);
dcb.fDtrControl = 1;//DTR = 0;接收
SetCommState(hComDev[ulChannelNo], &dcb);
Sleep(10);
if (dwRes != WAIT_OBJECT_0 || !GetOverlappedResult(hComDev[ulChannelNo], &stcWriteStatus[ulChannelNo], &iR, FALSE))
return 0;
return 0;
}
unsigned short CCA::CollectUARTData(const unsigned long ulCOMNo)
{
unsigned long ulLength = 0;
unsigned long ulEnd;
unsigned long ulStart;
#ifdef SYNCHRONOUS_MODE
WaitForSingleObject(hReceiveEvent[ulIndexCorrect], INFINITE);
ResetEvent(hReceiveEvent[ulIndexCorrect]);
#endif
ulEnd = ulUARTBufferEnd[ulCOMNo];
ulStart = ulUARTBufferStart[ulCOMNo];
if (ulEnd == ulStart)
return(0);
if (ulEnd > ulStart)
{
memcpy((void*)chrUARTBufferOutput, (void*)(chrUARTBuffers[ulCOMNo] + ulStart), ulEnd - ulStart);
ulLength = ulEnd - ulStart;
}
else
{
memcpy((void*)chrUARTBufferOutput, (void*)(chrUARTBuffers[ulCOMNo] + ulStart), UARTBufferLength - ulStart);
if (ulEnd != 0)
{
memcpy((void*)(chrUARTBufferOutput + (UARTBufferLength - ulStart)), (void*)chrUARTBuffers[ulCOMNo], ulEnd);
}
ulLength = UARTBufferLength + ulEnd - ulStart;
}
ulUARTBufferStart[ulCOMNo] = ulEnd;
return (unsigned short)ulLength;
}
signed char CCA::SetBaundrate(const unsigned long ulPortNo, const unsigned long ulBaundrate)
{
DCB dcb;
GetCommState(hComDev[ulPortNo], &dcb);
dcb.BaudRate = ulBaundrate;
SetCommState(hComDev[ulPortNo], &dcb);
return 0;
}
//靜態成員函數實現定義也不需要加static,並且內部可以調用static變量,
//但一般成員變量,static成員函數不可直接調用
DWORD WINAPI CCA::ReceiveCOMData(PVOID pParam)
{
unsigned long uLen;
unsigned long ulLen1;
unsigned long ulLen2;
DWORD dwRes;
COMSTAT Comstat;
DWORD dwErrorFlags;
char chrBuffer[iBufferSize] = { 0 };
unsigned long ulUARTBufferEndTemp = ulUARTBufferEnd[0];
unsigned long ulComNumber = 0;
memcpy(&ulComNumber, pParam, 4);
while (1)
{
if (!ReadFile(hComDev[ulComNumber], chrBuffer, iBufferSize - 1, &uLen, &(stcReadStatus[ulComNumber])))
{
dwRes = GetLastError();
if (dwRes != ERROR_IO_PENDING)
{
ClearCommError(hComDev[ulComNumber], &dwErrorFlags, &Comstat);
continue;
}
WaitForSingleObject(stcReadStatus[ulComNumber].hEvent, INFINITE);
if (!GetOverlappedResult(hComDev[ulComNumber], &(stcReadStatus[ulComNumber]), &uLen, FALSE))
continue;
if (uLen <= 0)
continue;
if ((ulUARTBufferEndTemp + uLen) > UARTBufferLength)
{
ulLen1 = UARTBufferLength - ulUARTBufferEndTemp;
ulLen2 = uLen - ulLen1;
if (ulLen1 > 0)
{
memcpy((void *)&chrUARTBuffers[ulComNumber][ulUARTBufferEnd[ulComNumber]], (void *)chrBuffer, ulLen1);
}
if (ulLen2 > 0)
{
memcpy((void *)&chrUARTBuffers[ulComNumber][0], (void *)(chrBuffer + ulLen1), ulLen2);
}
ulUARTBufferEndTemp = ulLen2;
}
else
{
memcpy((void *)&chrUARTBuffers[ulComNumber][ulUARTBufferEnd[ulComNumber]], (void *)chrBuffer, uLen);
ulUARTBufferEndTemp += uLen;
}
if (ulUARTBufferEndTemp == ulUARTBufferStart[ulComNumber])
{
printf("Error!");
}
else
{
ulUARTBufferEnd[ulComNumber] = ulUARTBufferEndTemp;
}
#ifdef SYNCHRONOUS_MODE
SetEvent(hReceiveEvent[ucComNumber]);
#endif
continue;
}
if (uLen <= 0)
continue;
if ((ulUARTBufferEndTemp + uLen) > (UARTBufferLength))
{
ulLen1 = UARTBufferLength - ulUARTBufferEndTemp;
ulLen2 = uLen - ulLen1;
if (ulLen1 > 0)
{
memcpy((void *)&chrUARTBuffers[ulComNumber][ulUARTBufferEnd[ulComNumber]], (void *)chrBuffer, ulLen1);
}
if (ulLen2 > 0)
{
memcpy((void *)&chrUARTBuffers[ulComNumber][0], (void *)(chrBuffer + ulLen1), ulLen2);
}
ulUARTBufferEndTemp = ulLen2;
}
else
{
memcpy((void *)&chrUARTBuffers[ulComNumber][ulUARTBufferEnd[ulComNumber]], (void *)chrBuffer, uLen);
ulUARTBufferEndTemp += uLen;
}
if (ulUARTBufferEndTemp == ulUARTBufferStart[ulComNumber])
{
printf("Error!");
}
else
{
ulUARTBufferEnd[ulComNumber] = ulUARTBufferEndTemp;
}
#ifdef SYNCHRONOUS_MODE
SetEvent(hReceiveEvent[ucComNumber]);
#endif
}
return 0;
}
signed char CCA::OpenCOMDevice(const unsigned long ulPortNo, const unsigned long ulBaundrate)
{
DWORD dwThreadID, dwThreadParam;
COMSTAT Comstat;
DWORD dwErrorFlags;
DWORD dwRes;
DCB dcb;
COMMTIMEOUTS comTimeOut;
TCHAR PortName[10] = { '\\','\\','.','\\','C','O','M',0,0,0 };//"\\\\.\\COM";
TCHAR chrTemple[5] = { 0 };
if (ulPortNo >= TOTAL_PORT_NUM)
{
printf("\nerror: exceed the max com port num\n");
return -1;
}
_itot(ulPortNo + START_PORT_NUM, chrTemple, 10);
_tcscat(PortName, chrTemple);
if ((hComDev[ulPortNo] = CreateFile(PortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)) == INVALID_HANDLE_VALUE)
{
dwRes = GetLastError();
return -1;
}
ulComMask |= 1 << ulPortNo;
SetupComm(hComDev[ulPortNo], iBufferSize, iBufferSize);
GetCommState(hComDev[ulPortNo], &dcb);
dcb.BaudRate = ulBaundrate;
dcb.fParity = NOPARITY;
dcb.ByteSize = 8;
dcb.fDtrControl = 1;//DTR = 0;接收
dcb.fRtsControl = 0;//RTS = 0;接收
dcb.StopBits = ONESTOPBIT;
SetCommState(hComDev[ulPortNo], &dcb);
ClearCommError(hComDev[ulPortNo], &dwErrorFlags, &Comstat);
dwRes = GetLastError();
comTimeOut.ReadIntervalTimeout = 5;
comTimeOut.ReadTotalTimeoutMultiplier = 10;
comTimeOut.ReadTotalTimeoutConstant = 100;
comTimeOut.WriteTotalTimeoutMultiplier = 5;
comTimeOut.WriteTotalTimeoutConstant = 5;
SetCommTimeouts(hComDev[ulPortNo], &comTimeOut);
stcWriteStatus[ulPortNo].hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
stcReadStatus[ulPortNo].hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
stcReadStatus[ulPortNo].Internal = 0;
stcReadStatus[ulPortNo].InternalHigh = 0;
stcReadStatus[ulPortNo].Offset = 0;
stcReadStatus[ulPortNo].OffsetHigh = 0;
dwThreadParam = ulPortNo;
hCOMThread[dwThreadParam] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReceiveCOMData, &dwThreadParam, 0, &dwThreadID);
SetThreadPriority(hCOMThread[ulPortNo], THREAD_PRIORITY_NORMAL);
Sleep(200);
return 0;
}
void CCA::CloseCOMDevice()
{
unsigned char i;
for (i = 0; i < sizeof(ulComMask) * 8; i++)
{
if ((ulComMask & (1 << i)) == 0)
continue;
ulUARTBufferEnd[i] = 0; ulUARTBufferStart[i] = 0;
TerminateThread(hCOMThread[i], 0);
WaitForSingleObject(hCOMThread[i], 10000);
PurgeComm(hComDev[i], PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
CloseHandle(stcReadStatus[i].hEvent);
CloseHandle(stcWriteStatus[i].hEvent);
CloseHandle(hComDev[i]);
}
ulComMask = 0;
}
.cpp文件中甚至不需要有export字眼的出現
注意:在項目屬性中,需要把生成改成.dll。
dll的調用
對類封裝好後的dll調用包括兩部分:
1.相關文件的放置
2.代碼書寫
1.相關文件放置
將編譯好的dll放入sln存在的x64文件夾中
將lib放入源代碼所在的lib文件夾中(沒有就自己新建一個)
.h文件放在源代碼所在的include文件夾中(沒有新建)
2.調用代碼
.h文件如下
#pragma once
#ifndef __COMANGLE_H__
#define __COMANGLE_H__
#include "windows.h"
#include <stdio.h>
#include <tchar.h>
//#ifdef _WIN32
//#ifdef CCA_API //這個在哪裏定義了?
#define CCA_API __declspec(dllexport)
//#else
//#define CCA_API __declspec(dllimport)
//#endif
//#else
//#define CCA_API __attribute__ ((visibility("default")))
//#endif
#ifndef JY901_h
#define JY901_h
#define SAVE 0x00
#define CALSW 0x01
#define RSW 0x02
#define RRATE 0x03
#define BAUD 0x04
#define AXOFFSET 0x05
#define AYOFFSET 0x06
#define AZOFFSET 0x07
#define GXOFFSET 0x08
#define GYOFFSET 0x09
#define GZOFFSET 0x0a
#define HXOFFSET 0x0b
#define HYOFFSET 0x0c
#define HZOFFSET 0x0d
#define D0MODE 0x0e
#define D1MODE 0x0f
#define D2MODE 0x10
#define D3MODE 0x11
#define D0PWMH 0x12
#define D1PWMH 0x13
#define D2PWMH 0x14
#define D3PWMH 0x15
#define D0PWMT 0x16
#define D1PWMT 0x17
#define D2PWMT 0x18
#define D3PWMT 0x19
#define IICADDR 0x1a
#define LEDOFF 0x1b
#define GPSBAUD 0x1c
#define YYMM 0x30
#define DDHH 0x31
#define MMSS 0x32
#define MS 0x33
#define AX 0x34
#define AY 0x35
#define AZ 0x36
#define GX 0x37
#define GY 0x38
#define GZ 0x39
#define HX 0x3a
#define HY 0x3b
#define HZ 0x3c
#define Roll 0x3d
#define Pitch 0x3e
#define Yaw 0x3f
#define TEMP 0x40
#define D0Status 0x41
#define D1Status 0x42
#define D2Status 0x43
#define D3Status 0x44
#define PressureL 0x45
#define PressureH 0x46
#define HeightL 0x47
#define HeightH 0x48
#define LonL 0x49
#define LonH 0x4a
#define LatL 0x4b
#define LatH 0x4c
#define GPSHeight 0x4d
#define GPSYAW 0x4e
#define GPSVL 0x4f
#define GPSVH 0x50
#define DIO_MODE_AIN 0
#define DIO_MODE_DIN 1
#define DIO_MODE_DOH 2
#define DIO_MODE_DOL 3
#define DIO_MODE_DOPWM 4
#define DIO_MODE_GPS 5
#define TOTAL_PORT_NUM 65
#define START_PORT_NUM 0
#define iBufferSize 250
#define UARTBufferLength 2000
#undef SYNCHRONOUS_MODE
struct STime
{
unsigned char ucYear;
unsigned char ucMonth;
unsigned char ucDay;
unsigned char ucHour;
unsigned char ucMinute;
unsigned char ucSecond;
unsigned short usMiliSecond;
};
struct SAcc
{
short a[3];
short T;
};
struct SGyro
{
short w[3];
short T;
};
struct SAngle
{
short Angle[3];
short T;
};
struct SMag
{
short h[3];
short T;
};
struct SDStatus
{
short sDStatus[4];
};
struct SPress
{
long lPressure;
long lAltitude;
};
struct SLonLat
{
long lLon;
long lLat;
};
struct SGPSV
{
short sGPSHeight;
short sGPSYaw;
long lGPSVelocity;
};
class CCA_API CCA
{
public:
struct STime stcTime;
struct SAcc stcAcc;
struct SGyro stcGyro;
struct SAngle stcAngle;
struct SMag stcMag;
struct SDStatus stcDStatus;
struct SPress stcPress;
struct SLonLat stcLonLat;
struct SGPSV stcGPSV;
//static成員變量須在類外定義
static HANDLE hComDev[TOTAL_PORT_NUM];
static unsigned long long ulComMask;
static HANDLE hCOMThread[TOTAL_PORT_NUM];
static OVERLAPPED stcWriteStatus[TOTAL_PORT_NUM];
static OVERLAPPED stcReadStatus[TOTAL_PORT_NUM];
static volatile char chrUARTBuffers[TOTAL_PORT_NUM][UARTBufferLength];
static volatile unsigned long ulUARTBufferStart[TOTAL_PORT_NUM];
static volatile unsigned long ulUARTBufferEnd[UARTBufferLength];
static char chrUARTBufferOutput[1000];
CCA();/*{}*/
void CopeSerialData(unsigned short usLength);
signed char SendUARTMessageLength(const unsigned long ulChannelNo, const char chrMessage[], const unsigned short usLen);
unsigned short CollectUARTData(const unsigned long ulChannelNo);
signed char SetBaundrate(const unsigned long ulPortNo, const unsigned long ulBaundrate);
signed char OpenCOMDevice(const unsigned long ulPortNo, const unsigned long ulBaundrate);
void CloseCOMDevice(void);
static DWORD WINAPI ReceiveCOMData(PVOID pParam);
~CCA();/* {}*/
};
extern CCA ComAngle;
#endif
#endif
.cpp文件夾
#include <iostream>
#include "time.h"
#include "windows.h"
#include ".\include\ComAngle.h"
#pragma comment(lib,"./lib/AngleDetectionV4.lib")
int main()
{
CCA Ccom_angle;
unsigned long ulBaund = 9600; unsigned long ulComNo = 4;
char chrBuffer[2000];
unsigned short usLength = 0, usCnt = 0;
signed char cResult = 1;
while (cResult != 0)
{
cResult = Ccom_angle.OpenCOMDevice(ulComNo, ulBaund);
}
while (1)
{
usLength = Ccom_angle.CollectUARTData(ulComNo);
if (usLength > 0)
{
//算法解析
Ccom_angle.CopeSerialData(usLength);
}
Sleep(100);
if (usCnt++ >= 0)
{
usCnt = 0;
float x = (float)Ccom_angle.stcAngle.Angle[0] / 32768 * 180;
float y = (float)Ccom_angle.stcAngle.Angle[1] / 32768 * 180;
float z = (float)Ccom_angle.stcAngle.Angle[2] / 32768 * 180;
std::cout << x << " " << y << " " << z << " " << std::endl;
}
}
}
以上就是整個類封裝成dll並調用的全過程,中間編譯的一些錯誤,需要對症下藥。預處理器,包含文件,#ifdef等都需要知道是幹嘛的。相關坑點也在代碼中有註釋。