学习研究Godot 4,很爽,虽然很庞杂,但相对于自己的水平来说,很强大,尤其是vulkan这块直接打包可用,省得自己从头琢磨。
一点一点地消化、优化与完善,最终才能成为自己的。
这段时间就在Godot的基础上,增加管道通信,实现Godot与本机已有程序进行通信,以备后续的无缝集成整合。
其实,Godot支持各种网络通信,支持UDP、TCP等。为什么非要实现管道通信,本质上还是想看看改造效果。最终目标是实现Godot软件与自己的DrGraph软件的管道通信
DrGraph端处理
为实现管道通信,根据Windows命名管道通信原理进行相应模块化实现。
class TDllData {
void __fastcall CheckType(unsigned char destType);
public:
__fastcall TDllData(unsigned char t = DRGRAPH_DLL_TYPE_NULL);
__fastcall TDllData(const TDllData& copy);
__fastcall ~TDllData();
bool __fastcall IsEof() { return type == DRGRAPH_DLL_TYPE_NULL; };
UnicodeString __fastcall GetHint();
unsigned char type;
union {
bool value_bool;
char value_char;
unsigned char value_uchar;
wchar_t value_wchar;
short value_short;
unsigned short value_ushort;
int value_int;
unsigned int value_uint;
long value_long;
unsigned long value_ulong;
double value_double;
long long value_longlong;
unsigned long long value_ulonglong;
} value ;
UnicodeString value_string;
TDllData * __fastcall operator = (const TDllData & equal);
operator bool();
operator char();
operator unsigned char();
operator wchar_t();
operator short();
operator unsigned short();
operator int();
operator unsigned int();
operator long();
operator unsigned long();
operator double();
operator long long();
operator unsigned long long();
operator UnicodeString();
};
class TDllStream : public CbwStream {
typedef CbwStream inherited;
TMemoryStream * FMemoryStream;
DRGRAPH_PROPERTY(bool, Finished);
DRGRAPH_PROPERTY(bool, WCharFlag);
DRGRAPH_PROPERTY(int, WCharSize);
public:
__fastcall TDllStream();
__fastcall TDllStream(BYTE * datas, int len);
__fastcall TDllStream(wchar_t * datas, int len);
__fastcall ~TDllStream();
void __fastcall Finish();
TDllData __fastcall Next();
void __fastcall Reset();
UnicodeString __fastcall GetHint(UnicodeString desc = L"");
int __fastcall NextFunType();
__fastcall operator BYTE *();
__fastcall operator wchar_t *();
virtual bool __fastcall writeBytes(const void * p, int len) {
CbwStream::writeBytes(p, len);
FFinished = false;
}
//#ifdef DRGRAPH_USE_OPENCV
// friend TDllStream & operator << (TDllStream & cofs, cv::Mat& mat);
// friend TDllStream & operator >> (TDllStream & cifs, cv::Mat& mat);
//#endif
friend TDllStream & operator << (TDllStream & cofs, NStreamIOControl ctrl) {
if(ctrl == ioReset)
cofs.Reset();
if(ctrl == ioRewind)
cofs.Rewind();
if(ctrl == ioFinish)
cofs.Finish();
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, bool value) {
DLL_WRITE(DRGRAPH_DLL_TYPE_BOOL);
if(cbw_debug_flag)
THelper::Logi(L"写入[%s]类型 > %s", DllType2String(dlltype), TTypeConvert::Bool2String(value));
unsigned char b = value ? 1 : 0;
cofs.writeBytes(&b, sizeof(unsigned char));
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, char value) {
DLL_WRITE(DRGRAPH_DLL_TYPE_CHAR);
if(cbw_debug_flag)
THelper::Logi(L"写入[%s]类型 > %d[0X%02X, %c]", DllType2String(dlltype), int(value), value, value);
cofs.writeBytes(&value, sizeof(char));
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, unsigned char value) {
DLL_WRITE(DRGRAPH_DLL_TYPE_UCHAR);
if(cbw_debug_flag)
THelper::Logi(L"写入[%s]类型 > %d[0X%02X, %c]", DllType2String(dlltype), int(value), value, value);
cofs.writeBytes(&value, sizeof(unsigned char));
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, wchar_t value) {
DLL_WRITE(DRGRAPH_DLL_TYPE_WCHAR);
if(cbw_debug_flag)
THelper::Logi(L"写入[%s]类型 > %s", DllType2String(dlltype), UnicodeString(value));
cofs.writeBytes(&value, sizeof(wchar_t));
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, short value) {
DLL_WRITE(DRGRAPH_DLL_TYPE_SHORT);
if(cbw_debug_flag)
THelper::Logi(L"写入[%s]类型 > %d", DllType2String(dlltype), int(value));
cofs.writeBytes(&value, sizeof(short));
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, unsigned short value) {
DLL_WRITE(DRGRAPH_DLL_TYPE_USHORT);
if(cbw_debug_flag)
THelper::Logi(L"写入[%s]类型 > %d", DllType2String(dlltype), int(value));
cofs.writeBytes(&value, sizeof(unsigned short));
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, int value) {
DLL_WRITE(DRGRAPH_DLL_TYPE_INT);
if(cbw_debug_flag)
THelper::Logi(L"写入[%s]类型 > %d", DllType2String(dlltype), int(value));
cofs.writeBytes(&value, sizeof(int));
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, unsigned int value) {
DLL_WRITE(DRGRAPH_DLL_TYPE_UINT);
if(cbw_debug_flag)
THelper::Logi(L"写入[%s]类型 > %d", DllType2String(dlltype), int(value));
cofs.writeBytes(&value, sizeof(unsigned int));
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, long value) {
DLL_WRITE(DRGRAPH_DLL_TYPE_LONG);
if(cbw_debug_flag)
THelper::Logi(L"写入[%s]类型 > %ld", DllType2String(dlltype), value);
cofs.writeBytes(&value, sizeof(long));
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, unsigned long value) {
DLL_WRITE(DRGRAPH_DLL_TYPE_ULONG);
if(cbw_debug_flag)
THelper::Logi(L"写入[%s]类型 > %lu", DllType2String(dlltype), value);
cofs.writeBytes(&value, sizeof(unsigned long));
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, long long value) {
DLL_WRITE(DRGRAPH_DLL_TYPE_LONGLONG);
if(cbw_debug_flag)
THelper::Logi(L"写入[%s]类型 > %lld", DllType2String(dlltype), value);
cofs.writeBytes(&value, sizeof(long long));
return cofs;
}
//
friend TDllStream & operator << (TDllStream & cofs, unsigned long long value) {
DLL_WRITE(DRGRAPH_DLL_TYPE_ULONGLONG);
if(cbw_debug_flag)
THelper::Logi(L"写入[%s]类型 > %llu", DllType2String(dlltype), value);
cofs.writeBytes(&value, sizeof(unsigned long long));
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, float value) {
double d = value;
cofs << d;
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, double value) {
DLL_WRITE(DRGRAPH_DLL_TYPE_DOUBLE);
if(cbw_debug_flag)
THelper::Logi(L"写入[%s]类型 > %s", DllType2String(dlltype), TTypeConvert::Double2String(value, 3));
cofs.writeBytes(&value, sizeof(double));
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, char*str) {
UnicodeString string = str;
cofs << string;
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, wchar_t*str) {
UnicodeString string = str;
cofs << string;
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, UnicodeString value) {
DLL_WRITE(DRGRAPH_DLL_TYPE_STRING);
if(cbw_debug_flag)
THelper::Logi(L"写入[%s]类型 > %s", DllType2String(dlltype), value);
int iTextLen = WideCharToMultiByte(CP_UTF8, 0, value.w_str(), -1, NULL, 0, NULL, NULL);
char * chBuffer = new char[iTextLen + 1];
WideCharToMultiByte(CP_UTF8, 0, value.w_str(), -1, chBuffer, iTextLen, NULL, NULL);
cofs.writeBytes(&iTextLen, sizeof(int));
cofs.writeBytes(chBuffer, iTextLen);
delete[]chBuffer;
return cofs;
}
friend TDllStream & operator >> (TDllStream & cifs, UnicodeString & q) {
int length;
cifs >> length;
char * chBuffer = new char[length + 1];
cifs.readBytes(chBuffer, length);
chBuffer[length] = '\0';
if(cifs.WCharFlag == false) {
int wLength = length + 1;
wchar_t *wcBuffer = new wchar_t[wLength];
MultiByteToWideChar(CP_UTF8, 0, chBuffer, wLength, wcBuffer, wLength);
wcBuffer[length] = L'\0';
q = UnicodeString(wcBuffer);
delete wcBuffer;
} else
q = UnicodeString(chBuffer);
delete chBuffer;
return cifs;
}
friend TDllStream & operator << (TDllStream & cofs, Variant& data) {
switch(data.Type()) {
case varBoolean: cofs << bool(data); break;
case varEmpty:
case varNull: cofs << 0; break;
case varSingle: cofs << float(data); break;
case varDouble: cofs << double(data); break;
case varString:
case varUString: cofs << (wchar_t *)(data); break;
case varSmallint:
case varInteger:
case varWord: cofs << int(data); break;
case varInt64: cofs << __int64(data); break;
case varUInt64: cofs << (unsigned __int64)(data); break;
case varByte: cofs << (unsigned char)(data); break;
case 0x10: cofs << short(data); break; // varShortInt
case varLongWord: cofs << long(data); break;
default: cofs << (wchar_t *)(data); break;
}
return cofs;
}
friend TDllStream & operator << (TDllStream & cofs, TDllData & data) {
if(data.type == DRGRAPH_DLL_TYPE_STRING)
cofs << data.value_string;
else if(data.type == DRGRAPH_DLL_TYPE_INT)
cofs << data.value.value_int;
else if(data.type == DRGRAPH_DLL_TYPE_DOUBLE)
cofs << data.value.value_double;
else if(data.type == DRGRAPH_DLL_TYPE_BOOL)
cofs << data.value.value_bool;
else if(data.type == DRGRAPH_DLL_TYPE_UCHAR)
cofs << data.value.value_uchar;
else if(data.type == DRGRAPH_DLL_TYPE_CHAR)
cofs << data.value.value_char;
else if(data.type == DRGRAPH_DLL_TYPE_WCHAR)
cofs << data.value.value_wchar;
else if(data.type == DRGRAPH_DLL_TYPE_SHORT)
cofs << data.value.value_short;
else if(data.type == DRGRAPH_DLL_TYPE_LONG)
cofs << data.value.value_long;
else if(data.type == DRGRAPH_DLL_TYPE_USHORT)
cofs << data.value.value_ushort;
else if(data.type == DRGRAPH_DLL_TYPE_UINT)
cofs << data.value.value_uint;
else if(data.type == DRGRAPH_DLL_TYPE_ULONG)
cofs << data.value.value_ulong;
else if(data.type == DRGRAPH_DLL_TYPE_LONGLONG)
cofs << data.value.value_longlong;
else if(data.type == DRGRAPH_DLL_TYPE_ULONGLONG)
cofs << data.value.value_ulonglong;
else if(data.type == DRGRAPH_DLL_TYPE_NULL)
cofs.Finish();
return cofs;
}
///////////////////////**************************************************************
friend TDllStream & operator >> (TDllStream & cifs, TDllData & data) {
if(data.type == DRGRAPH_DLL_TYPE_STRING)
cifs >> data.value_string;
else if(data.type == DRGRAPH_DLL_TYPE_INT)
cifs.readBytes(&data.value, sizeof(int));
else if(data.type == DRGRAPH_DLL_TYPE_DOUBLE)
cifs.readBytes(&data.value, sizeof(double));
else if(data.type == DRGRAPH_DLL_TYPE_BOOL)
cifs.readBytes(&data.value, sizeof(unsigned char));
else if(data.type == DRGRAPH_DLL_TYPE_UCHAR)
cifs.readBytes(&data.value, sizeof(unsigned char));
else if(data.type == DRGRAPH_DLL_TYPE_CHAR)
cifs.readBytes(&data.value, sizeof(char));
else if(data.type == DRGRAPH_DLL_TYPE_WCHAR)
cifs.readBytes(&data.value, sizeof(wchar_t));
else if(data.type == DRGRAPH_DLL_TYPE_SHORT)
cifs.readBytes(&data.value, sizeof(short));
else if(data.type == DRGRAPH_DLL_TYPE_LONG)
cifs.readBytes(&data.value, sizeof(long));
else if(data.type == DRGRAPH_DLL_TYPE_USHORT)
cifs.readBytes(&data.value, sizeof(unsigned short));
else if(data.type == DRGRAPH_DLL_TYPE_UINT)
cifs.readBytes(&data.value, sizeof(unsigned int));
else if(data.type == DRGRAPH_DLL_TYPE_ULONG)
cifs.readBytes(&data.value, sizeof(unsigned long));
else if(data.type == DRGRAPH_DLL_TYPE_LONGLONG)
cifs.readBytes(&data.value, sizeof(long long));
else if(data.type == DRGRAPH_DLL_TYPE_ULONG)
cifs.readBytes(&data.value, sizeof(unsigned long long));
else if(data.type == DRGRAPH_DLL_TYPE_NULL)
return cifs;
return cifs;
}
friend TDllStream & operator << (TDllStream & cofs, TPoint point) {
cofs << point.x;
cofs << point.y;
return cofs;
}
friend TDllStream & operator >> (TDllStream & cifs, TPoint& point) {
cifs >> point.x;
cifs >> point.y;
return cifs;
}
friend TDllStream & operator << (TDllStream & cofs, TRect rect) {
cofs << rect.left;
cofs << rect.top;
cofs << rect.right;
cofs << rect.bottom;
return cofs;
}
friend TDllStream & operator >> (TDllStream & cifs, TRect& rect) {
cifs >> rect.left;
cifs >> rect.top;
cifs >> rect.right;
cifs >> rect.bottom;
return cifs;
}
};
#define PIPE_CONNECTING_STATE 0
#define PIPE_READING_STATE 1
#define PIPE_WRITING_STATE 2
#define PIPE_INSTANCES 4
#define PIPE_TIMEOUT 5000
#define PIPE_BUFSIZE 4096
#define DRSTREAM_FUNCTION_NONE 0
#define DRSTREAM_FUNCTION_SET 1
#define DRSTREAM_FUNCTION_GET 2
#define DRSTREAM_FUNCTION_STATUS 3
typedef struct {
OVERLAPPED oOverlap;
HANDLE hPipeInst;
TCHAR wRequestBuffer[PIPE_BUFSIZE];
DWORD cbRead;
char wResponseBuffer[PIPE_BUFSIZE];
DWORD cbWrite;
DWORD dwState;
BOOL fPendingIO;
} PIPEINST, *LPPIPEINST;
class TPipeStream : public TDllStream {
class TPipeThread : public TThread {
friend class TPipeStream;
PIPEINST Pipe[PIPE_INSTANCES];
HANDLE hEvents[PIPE_INSTANCES];
private:
HANDLE hPipe;
TPipeStream * FOwnerStream;
void __fastcall Execute();
public:
__fastcall TPipeThread(TPipeStream * stream);
__fastcall ~TPipeThread();
void __fastcall DisconnectAndReconnect(DWORD);
bool __fastcall ConnectToNewClient(HANDLE, LPOVERLAPPED);

文章介绍了在Godot4中使用C++实现命名管道通信的详细过程,包括TDllStream类的设计,以及如何与自定义的DrGraph软件进行数据交换。此外,还展示了Godot端的GDScript绑定,以便在游戏引擎中使用该通信机制。
最低0.47元/天 解锁文章
3368

被折叠的 条评论
为什么被折叠?



