网站建设分金手指专业一,网页已改版,海报设计图片简单,免费ppt模板大全网址学习研究Godot 4#xff0c;很爽#xff0c;虽然很庞杂#xff0c;但相对于自己的水平来说#xff0c;很强大#xff0c;尤其是vulkan这块直接打包可用#xff0c;省得自己从头琢磨。
一点一点地消化、优化与完善#xff0c;最终才能成为自己的。
这段时间就在Godot的…学习研究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);
//#endiffriend 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;} elseq 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; // varShortIntcase 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 3typedef 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);bool __fastcall GetAnswerToRequest(LPPIPEINST pipe, int index);};DRGRAPH_PROPERTY(TObjectByNameEvent, OnFindObject);
public:__fastcall TPipeStream(UnicodeString pipeName);__fastcall ~TPipeStream();void __fastcall ReportError(UnicodeString desc);void __fastcall WritePipe(TDllStream os, int destPipeIndex -1);TPipeThread * PipeThread;DRGRAPH_PROPERTY(UnicodeString, PipeName);DRGRAPH_PROPERTY(UnicodeString, Prefix);DRGRAPH_PROPERTY(int, LastPipeIndex);
};
源程序实现 UnicodeString __fastcall TDllData::GetHint() {UnicodeString result FORMAT(L[%s]类型 值 , DllType2String(type));result type DRGRAPH_DLL_TYPE_BOOL ? TTypeConvert::Bool2String(value.value_bool) :type DRGRAPH_DLL_TYPE_CHAR ? FORMAT(L%d[0X%02X, %c], value.value_char, value.value_char, value.value_char) :type DRGRAPH_DLL_TYPE_UCHAR ? FORMAT(L%d[0X%02X, %c], value.value_uchar, value.value_uchar, value.value_uchar) :type DRGRAPH_DLL_TYPE_WCHAR ? FORMAT(L%s, UnicodeString(value.value_wchar)) :type DRGRAPH_DLL_TYPE_SHORT ? FORMAT(L%d, value.value_short) :type DRGRAPH_DLL_TYPE_USHORT ? FORMAT(L%d, value.value_ushort) :type DRGRAPH_DLL_TYPE_INT ? FORMAT(L%d, value.value_int) :type DRGRAPH_DLL_TYPE_UINT ? FORMAT(L%d, value.value_uint) :type DRGRAPH_DLL_TYPE_LONG ? FORMAT(L%ld, value.value_long) :type DRGRAPH_DLL_TYPE_ULONG ? FORMAT(L%lu, value.value_ulong) :type DRGRAPH_DLL_TYPE_LONGLONG ? FORMAT(L%lld, value.value_longlong) :type DRGRAPH_DLL_TYPE_ULONGLONG ? FORMAT(L%llu, value.value_ulonglong) :type DRGRAPH_DLL_TYPE_DOUBLE ? FORMAT(L%s, TTypeConvert::Double2String(value.value_double, 3)) :type DRGRAPH_DLL_TYPE_STRING ? FORMAT(L%s, value_string) :UnicodeString(L已结束);return result;
}void __fastcall TDllData::CheckType(unsigned char destType) {if(destType ! type)THelper::Logw(L类型不正确转换可能会出现偏差请检查协议 当前类型 %s, 目标类型: %s, DllType2String(type), DllType2String(destType));
}TDllData::operator bool() {CheckType(DRGRAPH_DLL_TYPE_BOOL);return value.value_bool;
}TDllData::operator char() {CheckType(DRGRAPH_DLL_TYPE_CHAR);return value.value_char;
}TDllData::operator unsigned char() {CheckType(DRGRAPH_DLL_TYPE_UCHAR);return value.value_uchar;
}TDllData::operator wchar_t() {CheckType(DRGRAPH_DLL_TYPE_WCHAR);return value.value_wchar;
}TDllData::operator short() {CheckType(DRGRAPH_DLL_TYPE_SHORT);return value.value_short;
}TDllData::operator unsigned short() {CheckType(DRGRAPH_DLL_TYPE_USHORT);return value.value_ushort;
}TDllData::operator int() {CheckType(DRGRAPH_DLL_TYPE_INT);return value.value_int;
}TDllData::operator unsigned int() {CheckType(DRGRAPH_DLL_TYPE_UINT);return value.value_uint;
}TDllData::operator long() {CheckType(DRGRAPH_DLL_TYPE_LONG);return value.value_long;
}TDllData::operator unsigned long() {CheckType(DRGRAPH_DLL_TYPE_ULONG);return value.value_ulong;
}TDllData::operator long long() {CheckType(DRGRAPH_DLL_TYPE_LONGLONG);return value.value_longlong;
}TDllData::operator unsigned long long() {CheckType(DRGRAPH_DLL_TYPE_ULONGLONG);return value.value_ulonglong;
}TDllData::operator double() {CheckType(DRGRAPH_DLL_TYPE_DOUBLE);return value.value_double;
}TDllData::operator UnicodeString() {CheckType(DRGRAPH_DLL_TYPE_STRING);return value_string;
}__fastcall TDllStream::TDllStream() : CbwStream() {FMemoryStream new TMemoryStream;Stream FMemoryStream;FFinished false;WCharFlag false;
}__fastcall TDllStream::TDllStream(BYTE * datas, int len) : CbwStream() {FMemoryStream new TMemoryStream;FMemoryStream-Write(datas, len);FMemoryStream-Position 0;Stream FMemoryStream;FFinished false;WCharFlag false;
}__fastcall TDllStream::TDllStream(wchar_t * datas, int len) {FMemoryStream new TMemoryStream;FMemoryStream-Write(datas, len);FMemoryStream-Position 0;Stream FMemoryStream;FFinished false;WCharFlag true;
}__fastcall TDllStream::~TDllStream() {
}void __fastcall TDllStream::Finish() {if(cbw_debug_flag)THelper::Logi(L结束...);if(FFinished)return;unsigned short value DRGRAPH_DLL_TYPE_NULL;writeBytes(value, sizeof(unsigned short));FFinished true;
}TDllData __fastcall TDllStream::Next() {unsigned char type;bool readed readBytes(type, sizeof(unsigned char));TDllData result(type);if(readed)(*this) result;return result;
}int __fastcall TDllStream::NextFunType() {if(Size - Position (sizeof(int) - 1))return 0;GET_DLL_DATA(int, funType, this);if(READING_DLL_DATA.type DRGRAPH_DLL_TYPE_NULL)funType DRSTREAM_FUNCTION_NONE;return funType;
}__fastcall TDllStream::operator BYTE *() {FMemoryStream-Position 0;int len Stream-Size;BYTE * result new BYTE[len];FMemoryStream-Read(result, len);FMemoryStream-Position 0;return result;
}__fastcall TDllStream::operator wchar_t *() {FMemoryStream-Position 0;int len Stream-Size;BYTE * result new BYTE[len];FMemoryStream-Read(result, len);FMemoryStream-Position 0;WCharSize MultiByteToWideChar(CP_ACP, 0, result, -1, NULL, 0);wchar_t * ws new wchar_t[WCharSize];MultiByteToWideChar(CP_ACP, 0, result, -1, ws, WCharSize);delete[] result;return ws;
}void __fastcall TDllStream::Reset() {CBW_DELETE(FMemoryStream);FMemoryStream new TMemoryStream;Stream FMemoryStream;
}UnicodeString __fastcall TDllStream::GetHint(UnicodeString desc) {UnicodeString result FORMAT(L%s中内容, desc.Length() 0 ? desc.w_str() : LDllStream流);do {if(EOF_Flag)break;TDllData data Next();if(data.IsEof())break;result FORMAT(L\n\t%s, data.GetHint());} while(true);return result;
}__fastcall TDllData::TDllData(unsigned char t) {type t;
}__fastcall TDllData::TDllData(const TDllData copy) {type copy.type;value copy.value;value_string copy.value_string;
}TDllData * __fastcall TDllData::operator (const TDllData equal) {type equal.type;value equal.value;value_string equal.value_string;return this;
}__fastcall TDllData::~TDllData() {
}__fastcall TPipeStream::TPipeStream(UnicodeString pipeName) {FPipeName pipeName;FPrefix FORMAT(L管道服务 %s, PipeName);OnFindObject NULL;PipeThread new TPipeThread(this);THelper::Logi(L创建 %s, FPrefix);
}__fastcall TPipeStream::~TPipeStream() {
}void __fastcall TPipeStream::ReportError(UnicodeString desc) {UnicodeString info FORMAT(L【%s.错误】 %s, FPrefix, desc);THelper::Loge(THelper::Util::GetSystemErrorInfo(false, info));
}__fastcall TPipeStream::TPipeThread::TPipeThread(TPipeStream * stream) : TThread(true) {FreeOnTerminate true;FOwnerStream stream;for (int i 0; i PIPE_INSTANCES; i)hEvents[i] NULL;Suspended false;
}__fastcall TPipeStream::TPipeThread::~TPipeThread() {if(FOwnerStream-PipeThread this)FOwnerStream-PipeThread NULL;
}void __fastcall TPipeStream::TPipeThread::DisconnectAndReconnect(DWORD i)
{if (!DisconnectNamedPipe(Pipe[i].hPipeInst))FOwnerStream-ReportError(DisconnectNamedPipe 失败);Pipe[i].fPendingIO ConnectToNewClient(Pipe[i].hPipeInst,Pipe[i].oOverlap);Pipe[i].dwState Pipe[i].fPendingIO ?PIPE_CONNECTING_STATE : // still connectingPIPE_READING_STATE; // ready to read
}// ConnectToNewClient(HANDLE, LPOVERLAPPED)
// This function is called to start an overlapped connect operation.
// It returns TRUE if an operation is pending or FALSE if the
// connection has been completed.bool __fastcall TPipeStream::TPipeThread::ConnectToNewClient(HANDLE hPipe, LPOVERLAPPED lpo)
{bool fConnected, fPendingIO false;fConnected ConnectNamedPipe(hPipe, lpo);if (fConnected){FOwnerStream-ReportError(L调用ConnectToNewClient时ConnectNamedPipe 失败 fConnected false);return 0;}switch (GetLastError()) {case ERROR_IO_PENDING: // The overlapped connection in progress.fPendingIO TRUE;break;case ERROR_PIPE_CONNECTED:// Client is already connected, so signal an event.if (SetEvent(lpo-hEvent))break;default: // If an error occurs during the connect operation...FOwnerStream-ReportError(调用ConnectToNewClient时ConnectNamedPipe 失败 GetLastError default);return 0;}return fPendingIO;
}void __fastcall TPipeStream::TPipeThread::Execute() {DWORD i, dwWait, cbRet, dwErr;BOOL fSuccess;THelper::Windows::DebugCurrentThread(ndttAdd, FORMAT(L【%s】, FOwnerStream-Prefix));LPTSTR lpszPipename TEXT(\\\\.\\pipe\\drgraph);// 创建多个命名管道for (i 0; i PIPE_INSTANCES; i) {hEvents[i] CreateEvent(NULL, // default security attributeTRUE, // manual-reset eventTRUE, // initial state signaledNULL); // unnamed event objectif (hEvents[i] NULL) {FOwnerStream-ReportError(CreateEvent failed);return;}Pipe[i].oOverlap.hEvent hEvents[i];Pipe[i].hPipeInst CreateNamedPipe(lpszPipename, // pipe namePIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // overlapped modePIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,PIPE_INSTANCES, // number of instancesPIPE_BUFSIZE*sizeof(TCHAR), // output buffer sizePIPE_BUFSIZE*sizeof(TCHAR), // input buffer sizePIPE_TIMEOUT, // client time-outNULL); // default security attributesif (Pipe[i].hPipeInst INVALID_HANDLE_VALUE) {FOwnerStream-ReportError(CreateNamedPipe failed);Pipe[i].hPipeInst NULL;return;}Pipe[i].fPendingIO ConnectToNewClient(Pipe[i].hPipeInst, Pipe[i].oOverlap);Pipe[i].dwState Pipe[i].fPendingIO ?PIPE_CONNECTING_STATE : // still connectingPIPE_READING_STATE; // ready to read}// 监听各管道while (!Terminated) {dwWait WaitForMultipleObjects(PIPE_INSTANCES, // number of event objectshEvents, // array of event objectsFALSE, // does not wait for all50);if( WAIT_TIMEOUT dwWait)continue;i dwWait - WAIT_OBJECT_0; // determines which pipeif (i 0 || i (PIPE_INSTANCES - 1)) {FOwnerStream-ReportError(FORMAT(WaitForMultipleObjects 监听结果下标[%d]越界 有效范围区间 (0 ~ %d), i, PIPE_INSTANCES - 1));break;}if (Pipe[i].fPendingIO) { // Get the result if the operation was pending.fSuccess GetOverlappedResult(Pipe[i].hPipeInst, // handle to pipePipe[i].oOverlap, // OVERLAPPED structurecbRet, // bytes transferredFALSE); // do not waitswitch (Pipe[i].dwState) { // Pending connect operationcase PIPE_CONNECTING_STATE:if (! fSuccess) {FOwnerStream-ReportError(FORMAT(调用GetOverlappedResult后Pipe[%d].dwState 值为 PIPE_CONNECTING_STATE 不再监听退出监听线程, i));return;}Pipe[i].dwState PIPE_READING_STATE;break;case PIPE_READING_STATE: // Pending read operationif (! fSuccess || cbRet 0) {DisconnectAndReconnect(i);continue;}Pipe[i].cbRead cbRet;Pipe[i].dwState PIPE_WRITING_STATE;break;case PIPE_WRITING_STATE: // Pending write operationif (! fSuccess || cbRet ! Pipe[i].cbWrite) {DisconnectAndReconnect(i);continue;}Pipe[i].dwState PIPE_READING_STATE;break;default:FOwnerStream-ReportError(FORMAT(调用GetOverlappedResult后Pipe[%d].dwState 值为未处理值[%d] 不再监听退出监听线程, Pipe[i].dwState));return;}}switch (Pipe[i].dwState) { // The pipe state determines which operation to do next.case PIPE_READING_STATE: // The pipe instance is connected to the clientfSuccess ReadFile( // and is ready to read a request from the client.Pipe[i].hPipeInst,Pipe[i].wRequestBuffer,PIPE_BUFSIZE*sizeof(TCHAR),Pipe[i].cbRead,Pipe[i].oOverlap);if (fSuccess Pipe[i].cbRead ! 0) { // The read operation completed successfully.Pipe[i].fPendingIO FALSE;Pipe[i].dwState PIPE_WRITING_STATE;continue;}// The read operation is still pending.dwErr GetLastError();if (! fSuccess (dwErr ERROR_IO_PENDING)) {Pipe[i].fPendingIO TRUE;continue;}DisconnectAndReconnect(i); // An error occurred; disconnect from the client.break;case PIPE_WRITING_STATE: // The request was successfully read from the client.GetAnswerToRequest(Pipe[i], i); // Get the reply data and write it to the client.fSuccess true;fSuccess WriteFile( // true: 有返回数据内容Pipe[i].hPipeInst,Pipe[i].wResponseBuffer,Pipe[i].cbWrite,cbRet,Pipe[i].oOverlap);if (fSuccess cbRet Pipe[i].cbWrite) { // The write operation completed successfully.Pipe[i].fPendingIO FALSE;Pipe[i].dwState PIPE_READING_STATE;continue;}// The write operation is still pending.dwErr GetLastError();if (! fSuccess (dwErr ERROR_IO_PENDING)) {Pipe[i].fPendingIO TRUE;continue;}DisconnectAndReconnect(i); // An error occurred; disconnect from the client.break;default:FOwnerStream-ReportError(Invalid pipe state.);return;}}THelper::Windows::DebugCurrentThread(ndttRemove);
}bool __fastcall TPipeStream::TPipeThread::GetAnswerToRequest(LPPIPEINST pipe, int index)
{FOwnerStream-LastPipeIndex index;TDllStream is(pipe-wRequestBuffer, pipe-cbRead);THelper::Logi(L接收到pipe[%d]信息 %s, index, is.GetHint());THelper::Debug::DoLogOutput();TDllStream os;OnRequest_Stream(is, os, FOwnerStream-OnFindObject);if(os.Size 0)os DRSTREAM_FUNCTION_NONE;// ERROR No Response;if(os.Size 0) {os ioFinish;os.Rewind();BYTE * data (BYTE *)os;pipe-cbWrite os.Size;memcpy(pipe-wResponseBuffer, data, os.Size);THelper::Logi(L发送 %d 字节 %s, pipe-cbWrite, os.GetHint());delete data;return true; // 有返回内容} return false;
}void __fastcall TPipeStream::WritePipe(TDllStream os, int destPipeIndex) {if(destPipeIndex -1) {destPipeIndex LastPipeIndex;if(destPipeIndex -1)destPipeIndex 0;}if(os.Size 0)os DRSTREAM_FUNCTION_NONE;if(os.Size 0) {os ioFinish;os.Rewind();BYTE * data (BYTE *)os;UnicodeString hint THelper::Debug::GetHint(data, os.Size);THelper::Logi(L[Pipe.发送] %s, hint);LPPIPEINST pipe (PipeThread-Pipe[destPipeIndex]);pipe-cbWrite os.Size;memcpy(pipe-wResponseBuffer, data, os.Size);DWORD i, dwWait, cbRet, dwErr;bool fSuccess WriteFile( // true: 有返回数据内容pipe-hPipeInst,data,os.Size,cbRet,NULL);if (fSuccess cbRet os.Size) { // The write operation completed successfully.THelper::Logi(L成功发送 %d 字节 %s, os.Size, os.GetHint());return;}THelper::Loge(L失败发送 %d 字节 %s, os.Size, os.GetHint());delete data;}
}在调用时简单声明即可访问其属性与方法。
void __fastcall TMainForm::Button_DebugTestClick(TObject *Sender)
{if(PipeStreamServer NULL) {CBW_DELETE(PipeStreamServer);PipeStreamServer new TPipeStream(Ldrgraph);PipeStreamServer-OnFindObject FindObjectByName;//FCurrentForm-FindMetaByName;} else {TDllStream dsStatus;dsStatus DRSTREAM_FUNCTION_STATUS LOK Ldrgraph.姓名 ArWen;PipeStreamServer-WritePipe(dsStatus);}
}
Godot端处理
直接在源码中增加CbwPipe.cpp与CbwPipe.h基于使用方法习惯相应编写实现
#pragma once#include core/os/os.h
#include stdarg.h
#include stdlib.hstd::string String2std(String str);
wchar_t *char32ToWchar(const char32_t *char32Str);
typedef unsigned char BYTE;
#define __property(type, var, read, write) __declspec(property(read, write)) type var#define DRSTREAM_FUNCTION_NONE 0
#define DRSTREAM_FUNCTION_SET 1
#define DRSTREAM_FUNCTION_GET 2
#define DRSTREAM_FUNCTION_STATUS 3enum SEEK_ORIGIN {SO_BEGINNING 0,SO_CURRENT 1,SO_END 2
};enum NStreamIOControl {ioReset,ioRewind,ioFinish
};extern bool cbw_debug_flag;
#define DRGRAPH_DLL_TYPE_NULL 0
#define DRGRAPH_DLL_TYPE_BOOL 1
#define DRGRAPH_DLL_TYPE_CHAR 2
#define DRGRAPH_DLL_TYPE_UCHAR 3
#define DRGRAPH_DLL_TYPE_WCHAR 4
#define DRGRAPH_DLL_TYPE_SHORT 5
#define DRGRAPH_DLL_TYPE_USHORT 6
#define DRGRAPH_DLL_TYPE_INT 7
#define DRGRAPH_DLL_TYPE_UINT 8
#define DRGRAPH_DLL_TYPE_LONG 9
#define DRGRAPH_DLL_TYPE_ULONG 10
#define DRGRAPH_DLL_TYPE_DOUBLE 11
#define DRGRAPH_DLL_TYPE_STRING 12
#define DRGRAPH_DLL_TYPE_LONGLONG 13
#define DRGRAPH_DLL_TYPE_ULONGLONG 14#define DLL_WRITE(t) \unsigned char dlltype t; \cofs.WriteBuffer(dlltype, sizeof(unsigned char)); \cofs.Finished false;std::string DllType2String(unsigned char type);
std::string Double2String(double value, int maxBits 8, int fixedFlag false, int width 0);
std::string WChar2String(wchar_t *pwszSrc);
std::string WChar2String(const wchar_t *pwszSrc);class TDllData {void CheckType(unsigned char destType);public:TDllData(unsigned char t DRGRAPH_DLL_TYPE_NULL);TDllData(const TDllData copy);~TDllData();bool IsEof() { return type DRGRAPH_DLL_TYPE_NULL; };std::string 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;std::string value_string;TDllData *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 std::string();
};class TDllStream {
public:enum { DEFAULT_MEMORY_DELTA 1024 }; // 默认内存步长enum { MIN_MEMORY_DELTA 256 }; // 最小内存步长private:char *m_pMemory; // 缓冲区指针int m_nSize; // 当前流的大小int m_nPosition; // 当前位置int m_nCapacity; // 缓冲区大小.真正大大小.包含给未来分配的长度int m_nMemoryDelta; // 增长的步长bool Finished;public:void SetPointer(void *pMemory, int nSize);void SetMemoryDelta(int nNewMemoryDelta);void SetCapacity(int nNewCapacity);char *Realloc(int nNewCapacity);int GetSize() const;void SetSize(int nSize);int GetPosition() const;void SetPosition(int nPos);int Read(void *pBuffer, int nCount);int Write(const void *pBuffer, int nCount);int Seek(int nOffset, SEEK_ORIGIN nSeekOrigin);public:explicit TDllStream(int nMemoryDelta DEFAULT_MEMORY_DELTA) :m_nCapacity(0), m_pMemory(NULL), m_nSize(0), m_nPosition(0) {SetMemoryDelta(nMemoryDelta);Finished false;}TDllStream(BYTE *datas, int len);~TDllStream();public:char *GetMemory() { return m_pMemory; }void *GetCurrentPtr() { return m_pMemory m_nPosition; }bool ReadBuffer(void *pBuffer, int nCount);bool WriteBuffer(void *pBuffer, int nCount);void Clear();bool IsEOF();void Rewind();void Finish();TDllData Next();void Reset();int NextFunType();operator BYTE *();__property(int, Size, get GetSize, put SetSize);__property(int, Position, get GetPosition, put SetPosition);public: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)OS::get_singleton()-print([DllStream] 写入[%s]类型 %s\n, DllType2String(dlltype).c_str(), value ? true : false);unsigned char b value ? 1 : 0;cofs.WriteBuffer(b, sizeof(unsigned char));return cofs;}friend TDllStream operator(TDllStream cofs, char value) {DLL_WRITE(DRGRAPH_DLL_TYPE_CHAR);if (cbw_debug_flag)OS::get_singleton()-print([DllStream] 写入[%s]类型 %d[0X%02X, %c]\n, DllType2String(dlltype).c_str(), int(value), value, value);cofs.WriteBuffer(value, sizeof(char));return cofs;}friend TDllStream operator(TDllStream cofs, unsigned char value) {DLL_WRITE(DRGRAPH_DLL_TYPE_UCHAR);if (cbw_debug_flag)OS::get_singleton()-print([DllStream] 写入[%s]类型 %d[0X%02X, %c]\n, DllType2String(dlltype).c_str(), int(value), value, value);cofs.WriteBuffer(value, sizeof(unsigned char));return cofs;}friend TDllStream operator(TDllStream cofs, wchar_t value) {DLL_WRITE(DRGRAPH_DLL_TYPE_WCHAR);if (cbw_debug_flag)OS::get_singleton()-print([DllStream] 写入[%s]类型 %lc\n, DllType2String(dlltype).c_str(), value);cofs.WriteBuffer(value, sizeof(wchar_t));return cofs;}friend TDllStream operator(TDllStream cofs, short value) {DLL_WRITE(DRGRAPH_DLL_TYPE_SHORT);if (cbw_debug_flag)OS::get_singleton()-print([DllStream] 写入[%s]类型 %d\n, DllType2String(dlltype).c_str(), int(value));cofs.WriteBuffer(value, sizeof(short));return cofs;}friend TDllStream operator(TDllStream cofs, unsigned short value) {DLL_WRITE(DRGRAPH_DLL_TYPE_USHORT);if (cbw_debug_flag)OS::get_singleton()-print([DllStream] 写入[%s]类型 %d\n, DllType2String(dlltype).c_str(), int(value));cofs.WriteBuffer(value, sizeof(unsigned short));return cofs;}friend TDllStream operator(TDllStream cofs, int value) {DLL_WRITE(DRGRAPH_DLL_TYPE_INT);if (cbw_debug_flag)OS::get_singleton()-print([DllStream] 写入[%s]类型 %d\n, DllType2String(dlltype).c_str(), int(value));cofs.WriteBuffer(value, sizeof(int));return cofs;}friend TDllStream operator(TDllStream cofs, unsigned int value) {DLL_WRITE(DRGRAPH_DLL_TYPE_UINT);if (cbw_debug_flag)OS::get_singleton()-print([DllStream] 写入[%s]类型 %d\n, DllType2String(dlltype).c_str(), int(value));cofs.WriteBuffer(value, sizeof(unsigned int));return cofs;}friend TDllStream operator(TDllStream cofs, long value) {DLL_WRITE(DRGRAPH_DLL_TYPE_LONG);if (cbw_debug_flag)OS::get_singleton()-print([DllStream] 写入[%s]类型 %ld\n, DllType2String(dlltype).c_str(), value);cofs.WriteBuffer(value, sizeof(long));return cofs;}friend TDllStream operator(TDllStream cofs, unsigned long value) {DLL_WRITE(DRGRAPH_DLL_TYPE_ULONG);if (cbw_debug_flag)OS::get_singleton()-print([DllStream] 写入[%s]类型 %lu\n, DllType2String(dlltype).c_str(), value);cofs.WriteBuffer(value, sizeof(unsigned long));return cofs;}friend TDllStream operator(TDllStream cofs, long long value) {DLL_WRITE(DRGRAPH_DLL_TYPE_LONGLONG);if (cbw_debug_flag)OS::get_singleton()-print([DllStream] 写入[%s]类型 %lld\n, DllType2String(dlltype).c_str(), value);cofs.WriteBuffer(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)OS::get_singleton()-print([DllStream] 写入[%s]类型 %llu\n, DllType2String(dlltype).c_str(), value);cofs.WriteBuffer(value, sizeof(unsigned long long));return cofs;}friend TDllStream operator(TDllStream cofs, float value) {//DLL_WRITE(DRGRAPH_DLL_TYPE_DOUBLE);double d value;cofs d;return cofs;}friend TDllStream operator(TDllStream cofs, double value) {DLL_WRITE(DRGRAPH_DLL_TYPE_DOUBLE);if (cbw_debug_flag)OS::get_singleton()-print([DllStream] 写入[%s]类型 %s\n, DllType2String(dlltype).c_str(), Double2String(value, 3).c_str());cofs.WriteBuffer(value, sizeof(double));return cofs;}friend TDllStream operator(TDllStream cofs, char *str) {std::string string str;cofs string;return cofs;}friend TDllStream operator(TDllStream cofs, const char *str) {std::string string str;cofs string;return cofs;}friend TDllStream operator(TDllStream cofs, const char32_t *str) {std::string result String2std(str);cofs result;return cofs;}friend TDllStream operator(TDllStream cofs, wchar_t *str) {std::string string WChar2String(str);cofs string;return cofs;}friend TDllStream operator(TDllStream cofs, const wchar_t *str) {std::string string WChar2String(str);cofs string;return cofs;}friend TDllStream operator(TDllStream cofs, std::string value);friend TDllStream operator(TDllStream cofs, String str) {std::string string String2std(str);cofs string;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, bool q) {unsigned char b;cifs b;q b;return cifs;}friend TDllStream operator(TDllStream cifs, char q) {cifs.ReadBuffer(q, sizeof(char));return cifs;}friend TDllStream operator(TDllStream cifs, signed char q) {cifs.ReadBuffer(q, sizeof(signed char));return cifs;}friend TDllStream operator(TDllStream cifs, unsigned char q) {cifs.ReadBuffer(q, sizeof(unsigned char));return cifs;}friend TDllStream operator(TDllStream cifs, signed short q) {cifs.ReadBuffer(q, sizeof(signed short));return cifs;}friend TDllStream operator(TDllStream cifs, unsigned short q) {cifs.ReadBuffer(q, sizeof(unsigned short));return cifs;}friend TDllStream operator(TDllStream cifs, signed int q) {cifs.ReadBuffer(q, sizeof(signed int));return cifs;}friend TDllStream operator(TDllStream cifs, unsigned int q) {cifs.ReadBuffer(q, sizeof(unsigned int));return cifs;}friend TDllStream operator(TDllStream cifs, signed long q) {cifs.ReadBuffer(q, sizeof(signed long));return cifs;}friend TDllStream operator(TDllStream cifs, unsigned long q) {cifs.ReadBuffer(q, sizeof(unsigned long));return cifs;}friend TDllStream operator(TDllStream cifs, float q) {cifs.ReadBuffer(q, sizeof(float));return cifs;}friend TDllStream operator(TDllStream cifs, double q) {cifs.ReadBuffer(q, sizeof(double));return cifs;}friend TDllStream operator(TDllStream cifs, long double q) {cifs.ReadBuffer(q, sizeof(long double));return cifs;}friend TDllStream operator(TDllStream cifs, std::string q);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.ReadBuffer(data.value, sizeof(int));else if (data.type DRGRAPH_DLL_TYPE_DOUBLE)cifs.ReadBuffer(data.value, sizeof(double));else if (data.type DRGRAPH_DLL_TYPE_BOOL)cifs.ReadBuffer(data.value, sizeof(unsigned char));else if (data.type DRGRAPH_DLL_TYPE_UCHAR)cifs.ReadBuffer(data.value, sizeof(unsigned char));else if (data.type DRGRAPH_DLL_TYPE_CHAR)cifs.ReadBuffer(data.value, sizeof(char));else if (data.type DRGRAPH_DLL_TYPE_WCHAR)cifs.ReadBuffer(data.value, sizeof(wchar_t));else if (data.type DRGRAPH_DLL_TYPE_SHORT)cifs.ReadBuffer(data.value, sizeof(short));else if (data.type DRGRAPH_DLL_TYPE_LONG)cifs.ReadBuffer(data.value, sizeof(long));else if (data.type DRGRAPH_DLL_TYPE_USHORT)cifs.ReadBuffer(data.value, sizeof(unsigned short));else if (data.type DRGRAPH_DLL_TYPE_UINT)cifs.ReadBuffer(data.value, sizeof(unsigned int));else if (data.type DRGRAPH_DLL_TYPE_ULONG)cifs.ReadBuffer(data.value, sizeof(unsigned long));else if (data.type DRGRAPH_DLL_TYPE_LONGLONG)cifs.ReadBuffer(data.value, sizeof(long long));else if (data.type DRGRAPH_DLL_TYPE_ULONG)cifs.ReadBuffer(data.value, sizeof(unsigned long long));else if (data.type DRGRAPH_DLL_TYPE_NULL)return cifs;return cifs;}
};
extern TDllData READING_DLL_DATA;#define DRGRAPH_SOURCE_POS str_format(%s[%d] - %S(), \std::string(__FILE__), __LINE__, __func__)#define GET_DLL_DATA(T, varName, is) \READING_DLL_DATA (is)-Next(); \T varName; \if (READING_DLL_DATA.type ! DRGRAPH_DLL_TYPE_NULL) { \if (READING_DLL_DATA.IsEof()) { \std::string msg str_format(越界读取〖%S %S; %s〗请检查协议..., typeid(T).name(), #varName, DRGRAPH_SOURCE_POS); \throw(msg); \} \varName READING_DLL_DATA; \}class TCbwPipe {void *g_hNamedPipe; // 管道句柄bool CreateNamePipeC(const char *iPipeName); // 创建命名管道客户端std::string FPipeServerName;static TCbwPipe *singleton;public:void ReadPipeData(BYTE *iBuffer, int iBufferSize, int timeout 1000); // 读取数据bool WriteDllStream(TDllStream os, int timeout 1000);public:TCbwPipe();~TCbwPipe();bool ConnectToServer(std::string pipeServerName);static TCbwPipe *get_singleton();static void Free();
};std::string String2std(String str);
#include CbwPipe.h#include stdarg.h
#include thread#include locale.h
#include windows.h
#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
#include codecvtstd::string String2std(String str) {//std::wstring_convertstd::codecvt_utf8char32_t, char32_t converter;//std::string result converter.to_bytes(str.ptr());wchar_t *wchar char32ToWchar(str.ptr());std::wstring_convertstd::codecvt_utf8wchar_t, wchar_t converter;std::string result converter.to_bytes(wchar);delete[] wchar;return result;
}wchar_t *char32ToWchar(const char32_t *char32Str) {std::wstring_convertstd::codecvt_utf8char32_t, char32_t converter;// 将 char32_t* 转换为 UTF-8 编码的 std::stringstd::string utf8Str converter.to_bytes(char32Str);// 计算宽字符字符串所需的长度size_t wideLen mbstowcs(nullptr, utf8Str.c_str(), 0) 1;// 分配内存并转换为宽字符字符串wchar_t *wcharStr new wchar_t[wideLen];mbstowcs(wcharStr, utf8Str.c_str(), wideLen);return wcharStr;
}TDllStream operator(TDllStream cofs, std::string value) {DLL_WRITE(DRGRAPH_DLL_TYPE_STRING);if (cbw_debug_flag)OS::get_singleton()-print([DllStream] 写入[%s]类型 %s\n, DllType2String(dlltype).c_str(), value.c_str());int wideCharLen MultiByteToWideChar(CP_UTF8, 0, value.c_str(), value.length() 1, nullptr, 0);wchar_t *wideCharStr new wchar_t[wideCharLen];int multiByteLen WideCharToMultiByte(CP_UTF8, 0, wideCharStr, wideCharLen, nullptr, 0, nullptr, nullptr);char *multiByteStr new char[multiByteLen];WideCharToMultiByte(CP_UTF8, 0, wideCharStr, wideCharLen, multiByteStr, multiByteLen, nullptr, nullptr);cofs.WriteBuffer(multiByteLen, sizeof(int));cofs.WriteBuffer((void *)multiByteStr, multiByteLen);delete[] wideCharStr;delete[] multiByteStr;return cofs;
}bool cbw_debug_flag true;TDllStream operator(TDllStream cifs, std::string q) {int length;cifs length;char *chBuffer new char[length 1];cifs.ReadBuffer(chBuffer, length);int wLength length 1;wchar_t *wcBuffer new wchar_t[wLength];MultiByteToWideChar(CP_UTF8, 0, chBuffer, wLength, wcBuffer, wLength);q WChar2String(wcBuffer);delete wcBuffer;delete chBuffer;return cifs;
}
template typename... Args
static std::string str_format(const std::string format, Args... args) {auto size_buf std::snprintf(nullptr, 0, format.c_str(), args...) 1;std::unique_ptrchar[] buf(new (std::nothrow) char[size_buf]);if (!buf)return std::string();std::snprintf(buf.get(), size_buf, format.c_str(), args...);return std::string(buf.get(), buf.get() size_buf - 1);
}std::string Double2String(double value, int maxBits, int fixedFlag, int width) {std::string result str_format(%f, value);size_t pointPos result.find(.);if (pointPos 0) {size_t floatNumber result.length() - pointPos;if (floatNumber maxBits)result.erase(pointPos maxBits 1, result.length());if (pointPos 0)result str_format(0%s, result);}for (size_t i result.length() - 1; i 0; --i) {if (result.c_str()[i] 0)result.erase(i 1, 1);elsebreak;}if (result.length() 0 result.c_str()[result.length() - 1] L.)result.erase(result.length(), 1);if (fixedFlag) {size_t pointPos result.find(.);if (pointPos result.npos) {result .;pointPos result.length();}int floatNumber result.length() - pointPos;while (floatNumber maxBits)result 0;}int blankNumber width - result.length();if (blankNumber 0) {std::string pre;pre.resize(blankNumber, );result pre result;}return result;
}std::string WChar2String(wchar_t *pwszSrc) {int nLen WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);if (nLen 0)return std::string();char *pszDst new char[nLen];if (NULL pszDst)return std::string();WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);pszDst[nLen - 1] 0;std::string strTemp(pszDst);delete[] pszDst;return strTemp;
}std::string WChar2String(const wchar_t *pwszSrc) {return WChar2String(const_castwchar_t *(pwszSrc));
}std::string DllType2String(unsigned char type) {std::string result type DRGRAPH_DLL_TYPE_NULL ? 结束: type DRGRAPH_DLL_TYPE_BOOL ? bool: type DRGRAPH_DLL_TYPE_CHAR ? char: type DRGRAPH_DLL_TYPE_UCHAR ? BYTE: type DRGRAPH_DLL_TYPE_WCHAR ? wchar_t: type DRGRAPH_DLL_TYPE_SHORT ? short: type DRGRAPH_DLL_TYPE_USHORT ? unsigned short: type DRGRAPH_DLL_TYPE_INT ? int: type DRGRAPH_DLL_TYPE_UINT ? unsigned int: type DRGRAPH_DLL_TYPE_LONG ? long: type DRGRAPH_DLL_TYPE_ULONG ? unsigned long: type DRGRAPH_DLL_TYPE_DOUBLE ? double: type DRGRAPH_DLL_TYPE_STRING ? string: type DRGRAPH_DLL_TYPE_LONGLONG ? long long: type DRGRAPH_DLL_TYPE_ULONGLONG ? unsigned long long: 未知类型;return result;
}std::string VarType2String(Variant::Type t) {switch (t) {case Variant::NIL:return NIL;case Variant::BOOL:return BOOL;case Variant::INT:return INT;case Variant::FLOAT:return FLOAT;case Variant::STRING:return STRING;case Variant::VECTOR2:return VECTOR2;case Variant::VECTOR2I:return VECTOR2I;case Variant::RECT2:return RECT2;case Variant::RECT2I:return RECT2I;case Variant::VECTOR3:return VECTOR3;case Variant::VECTOR3I:return VECTOR3I;case Variant::TRANSFORM2D:return TRANSFORM2D;case Variant::VECTOR4:return VECTOR4;case Variant::VECTOR4I:return VECTOR4I;case Variant::PLANE:return PLANE;case Variant::QUATERNION:return QUATERNION;case Variant::AABB:return AABB;case Variant::BASIS:return BASIS;case Variant::TRANSFORM3D:return TRANSFORM3D;case Variant::PROJECTION:return PROJECTION;case Variant::COLOR:return COLOR;case Variant::STRING_NAME:return STRING_NAME;case Variant::NODE_PATH:return NODE_PATH;case Variant::RID:return RID;case Variant::OBJECT:return OBJECT;case Variant::CALLABLE:return CALLABLE;case Variant::SIGNAL:return SIGNAL;case Variant::DICTIONARY:return DICTIONARY;case Variant::ARRAY:return ARRAY;case Variant::PACKED_BYTE_ARRAY:return PACKED_BYTE_ARRAY;case Variant::PACKED_INT32_ARRAY:return PACKED_INT32_ARRAY;case Variant::PACKED_INT64_ARRAY:return PACKED_INT64_ARRAY;case Variant::PACKED_FLOAT32_ARRAY:return PACKED_FLOAT32_ARRAY;case Variant::PACKED_FLOAT64_ARRAY:return PACKED_FLOAT64_ARRAY;case Variant::PACKED_STRING_ARRAY:return PACKED_STRING_ARRAY;case Variant::PACKED_VECTOR2_ARRAY:return PACKED_VECTOR2_ARRAY;case Variant::PACKED_VECTOR3_ARRAY:return PACKED_VECTOR3_ARRAY;case Variant::PACKED_COLOR_ARRAY:return PACKED_COLOR_ARRAY;case Variant::VARIANT_MAX:return VARIANT_MAX;default:return UNKNOWN;}
}TDllData READING_DLL_DATA;TDllData::TDllData(unsigned char t) {type t;
}TDllData::TDllData(const TDllData copy) {type copy.type;value copy.value;value_string copy.value_string;
}TDllData::~TDllData() {
}std::string TDllData::GetHint() {std::string result str_format([%s]类型 值 , DllType2String(type));result type DRGRAPH_DLL_TYPE_BOOL ? (value.value_bool ? true : false): type DRGRAPH_DLL_TYPE_CHAR ? str_format(%d[0X%02X, %c], value.value_char, value.value_char, value.value_char): type DRGRAPH_DLL_TYPE_UCHAR ? str_format(%d[0X%02X, %c], value.value_uchar, value.value_uchar, value.value_uchar): type DRGRAPH_DLL_TYPE_WCHAR ? str_format(%lc, value.value_wchar): type DRGRAPH_DLL_TYPE_SHORT ? str_format(%d, value.value_short): type DRGRAPH_DLL_TYPE_USHORT ? str_format(%d, value.value_ushort): type DRGRAPH_DLL_TYPE_INT ? str_format(%d, value.value_int): type DRGRAPH_DLL_TYPE_UINT ? str_format(%d, value.value_uint): type DRGRAPH_DLL_TYPE_LONG ? str_format(%ld, value.value_long): type DRGRAPH_DLL_TYPE_ULONG ? str_format(%lu, value.value_ulong): type DRGRAPH_DLL_TYPE_LONGLONG ? str_format(%lld, value.value_longlong): type DRGRAPH_DLL_TYPE_ULONGLONG ? str_format(%llu, value.value_ulonglong): type DRGRAPH_DLL_TYPE_DOUBLE ? str_format(%s, Double2String(value.value_double, 3)): type DRGRAPH_DLL_TYPE_STRING ? str_format(%s, value_string): str_format(已结束);return result;
}void TDllData::CheckType(unsigned char destType) {if (destType ! type)OS::get_singleton()-print(类型不正确转换可能会出现偏差请检查协议 当前类型 %s, 目标类型: %s,DllType2String(type).c_str(), DllType2String(destType).c_str());
}TDllData *TDllData::operator(const TDllData equal) {type equal.type;value equal.value;value_string equal.value_string;return this;
}TDllData::operator bool() {CheckType(DRGRAPH_DLL_TYPE_BOOL);return value.value_bool;
}TDllData::operator char() {CheckType(DRGRAPH_DLL_TYPE_CHAR);return value.value_char;
}TDllData::operator unsigned char() {CheckType(DRGRAPH_DLL_TYPE_UCHAR);return value.value_uchar;
}TDllData::operator wchar_t() {CheckType(DRGRAPH_DLL_TYPE_WCHAR);return value.value_wchar;
}TDllData::operator short() {CheckType(DRGRAPH_DLL_TYPE_SHORT);return value.value_short;
}TDllData::operator unsigned short() {CheckType(DRGRAPH_DLL_TYPE_USHORT);return value.value_ushort;
}TDllData::operator int() {CheckType(DRGRAPH_DLL_TYPE_INT);return value.value_int;
}TDllData::operator unsigned int() {CheckType(DRGRAPH_DLL_TYPE_UINT);return value.value_uint;
}TDllData::operator long() {CheckType(DRGRAPH_DLL_TYPE_LONG);return value.value_long;
}TDllData::operator unsigned long() {CheckType(DRGRAPH_DLL_TYPE_ULONG);return value.value_ulong;
}TDllData::operator long long() {CheckType(DRGRAPH_DLL_TYPE_LONGLONG);return value.value_longlong;
}TDllData::operator unsigned long long() {CheckType(DRGRAPH_DLL_TYPE_ULONGLONG);return value.value_ulonglong;
}TDllData::operator double() {CheckType(DRGRAPH_DLL_TYPE_DOUBLE);return value.value_double;
}TDllData::operator std::string() {CheckType(DRGRAPH_DLL_TYPE_STRING);return value_string;
}void TDllStream::SetPointer(void *pMemory, int nSize) {m_pMemory (char *)pMemory;m_nSize nSize;
}void TDllStream::SetMemoryDelta(int nNewMemoryDelta) {if (nNewMemoryDelta ! DEFAULT_MEMORY_DELTA) {if (nNewMemoryDelta MIN_MEMORY_DELTA)nNewMemoryDelta MIN_MEMORY_DELTA;// 2^Nfor (int i sizeof(int) * 8 - 1; i 0; i--)if (((1 i) nNewMemoryDelta) ! 0) {nNewMemoryDelta (1 i);break;}}m_nMemoryDelta nNewMemoryDelta;
}void TDllStream::SetCapacity(int nNewCapacity) {SetPointer(Realloc(nNewCapacity), m_nSize);m_nCapacity nNewCapacity;
}char *TDllStream::Realloc(int nNewCapacity) {char *pResult;if (nNewCapacity 0 nNewCapacity ! m_nSize)nNewCapacity (nNewCapacity (m_nMemoryDelta - 1)) ~(m_nMemoryDelta - 1);pResult m_pMemory;if (nNewCapacity ! m_nCapacity) {if (nNewCapacity 0) {free(m_pMemory);pResult NULL;} else {if (m_nCapacity 0)pResult (char *)malloc(nNewCapacity);elsepResult (char *)realloc(m_pMemory, nNewCapacity);}}return pResult;
}int TDllStream::GetSize() const {int nPos, nResult;nPos const_castTDllStream (*this).Seek(0, SO_CURRENT);nResult const_castTDllStream (*this).Seek(0, SO_END);const_castTDllStream (*this).Seek(nPos, SO_BEGINNING);return nResult;
}void TDllStream::SetSize(int nSize) {int nOldPos m_nPosition;SetCapacity((int)nSize);m_nSize (int)nSize;if (nOldPos nSize)Seek(0, SO_END);
}int TDllStream::GetPosition() const {return const_castTDllStream (*this).Seek(0, SO_CURRENT);
}void TDllStream::SetPosition(int nPos) {Seek(nPos, SO_BEGINNING);
}int TDllStream::Read(void *pBuffer, int nCount) {int nResult 0;if (m_nPosition 0 nCount 0) {nResult m_nSize - m_nPosition;if (nResult 0) {if (nResult nCount)nResult nCount;memmove(pBuffer, m_pMemory (DWORD)m_nPosition, nResult);m_nPosition nResult;}}return nResult;
}int TDllStream::Write(const void *pBuffer, int nCount) {int nResult 0;int nPos;if (m_nPosition 0 nCount 0) {nPos m_nPosition nCount;if (nPos 0) {if (nPos m_nSize) {if (nPos m_nCapacity)SetCapacity(nPos);m_nSize nPos;}memmove(m_pMemory (DWORD)m_nPosition, pBuffer, nCount);m_nPosition nPos;nResult nCount;}}return nResult;
}TDllStream::TDllStream(BYTE *datas, int len) :m_nCapacity(0), m_pMemory(NULL), m_nSize(0), m_nPosition(0) {SetMemoryDelta(DEFAULT_MEMORY_DELTA);Clear();WriteBuffer(datas, len);Finished false;Rewind();
}TDllStream::~TDllStream() {Clear();
}int TDllStream::Seek(int nOffset, SEEK_ORIGIN nSeekOrigin) {switch (nSeekOrigin) {case SO_BEGINNING:m_nPosition (int)nOffset;break;case SO_CURRENT:m_nPosition (int)nOffset;break;case SO_END:m_nPosition m_nSize (int)nOffset;break;}return m_nPosition;
}bool TDllStream::ReadBuffer(void *pBuffer, int nCount) {if (nCount ! 0 Read(pBuffer, nCount) ! nCount)return false;elsereturn true;
}bool TDllStream::WriteBuffer(void *pBuffer, int nCount) {if (nCount ! 0 Write(pBuffer, nCount) ! nCount)return false;elsereturn true;
}void TDllStream::Clear() {SetCapacity(0);m_nSize 0;m_nPosition 0;
}bool TDllStream::IsEOF() {return Position Size;
}void TDllStream::Rewind() {Position 0;
}void TDllStream::Finish() {unsigned short value DRGRAPH_DLL_TYPE_NULL;WriteBuffer(value, sizeof(unsigned short));Finished true;
}TDllData TDllStream::Next() {unsigned char type;bool readed ReadBuffer(type, sizeof(unsigned char));TDllData result(type);if (readed)(*this) result;return result;
}void TDllStream::Reset() {Clear();
}int TDllStream::NextFunType() {if (Size - Position 2)return 0;GET_DLL_DATA(int, funType, this);if (READING_DLL_DATA.type DRGRAPH_DLL_TYPE_NULL)funType DRSTREAM_FUNCTION_NONE;return funType;
}TDllStream::operator BYTE *() {Position 0;int len Size;BYTE *result new BYTE[len];ReadBuffer(result, len);Position 0;return result;
}TCbwPipe *TCbwPipe::singleton nullptr;
TCbwPipe *TCbwPipe::get_singleton() {if (!TCbwPipe::singleton) {TCbwPipe::singleton new TCbwPipe();}return TCbwPipe::singleton;
}void TCbwPipe::Free() {if (TCbwPipe::singleton)delete TCbwPipe::singleton;TCbwPipe::singleton NULL;
}TCbwPipe::TCbwPipe() {setlocale(LC_ALL, );g_hNamedPipe INVALID_HANDLE_VALUE;
}TCbwPipe::~TCbwPipe() {if (g_hNamedPipe ! INVALID_HANDLE_VALUE g_hNamedPipe ! NULL)CloseHandle(g_hNamedPipe);
}bool TCbwPipe::CreateNamePipeC(const char *iPipeName) {char t_PipeName[200];//1,创建一个命名管道sprintf_s(t_PipeName, \\\\.\\pipe\\%s, iPipeName);if (WaitNamedPipeA(t_PipeName, NMPWAIT_WAIT_FOREVER) 0) {OS::get_singleton()-print(当前没有可以利用的管道:%d\n, GetLastError());return false;}g_hNamedPipe CreateFileA(t_PipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (g_hNamedPipe INVALID_HANDLE_VALUE) {OS::get_singleton()-print(打开命名管道失败!:%d\n, GetLastError());g_hNamedPipe NULL;return false;}OS::get_singleton()-print(链接管道%s已成功\n, t_PipeName);return true;
}
#include iomanip
#include iostream
#include sstream
// 读取数据
void TCbwPipe::ReadPipeData(BYTE *iBuffer, int iBufferSize, int timeout) {DWORD availableBytes;if (g_hNamedPipe INVALID_HANDLE_VALUE) {OS::get_singleton()-is_pipe_allowed false;return;}if (!PeekNamedPipe(g_hNamedPipe, NULL, 0, NULL, availableBytes, NULL)) {OS::get_singleton()-print([Pipe.Read] 读取数据失败:%d\n, GetLastError());if (g_hNamedPipe ! INVALID_HANDLE_VALUE g_hNamedPipe ! NULL)CloseHandle(g_hNamedPipe);g_hNamedPipe INVALID_HANDLE_VALUE;OS::get_singleton()-is_pipe_allowed false;return;}if (availableBytes 1) {iBufferSize 0;return;}//读取数据DWORD dwRead;HANDLE t_hEvent CreateEvent(NULL, TRUE, FALSE, NULL);OVERLAPPED ovlap;ZeroMemory(ovlap, sizeof(OVERLAPPED));ovlap.hEvent t_hEvent;if (ReadFile(g_hNamedPipe, iBuffer, iBufferSize, dwRead, ovlap) false) {OS::get_singleton()-print([Pipe.Read] 读取数据失败:%d\n, GetLastError());if (t_hEvent)CloseHandle(t_hEvent);t_hEvent NULL;iBufferSize 0;return;}iBufferSize 0;if (t_hEvent) {bool failed (WaitForSingleObject(t_hEvent, timeout) WAIT_FAILED);CloseHandle(t_hEvent);t_hEvent NULL;if (failed) {OS::get_singleton()-print([Pipe.Read] 等待对象失败:%d\n, GetLastError());return;}}if (dwRead 0) {iBufferSize dwRead;std::ostringstream oss{};//oss [Pipe.Read] 接收到数据 ;for (DWORD i 0; i dwRead; i)oss std::hex iBuffer[i] , ;oss std::endl;std::string str oss.str();OS::get_singleton()-print([Pipe.Read] 接收到数据 %s\n, str.c_str());TDllStream cifs(iBuffer, dwRead);do {int funType cifs.NextFunType();if (funType DRSTREAM_FUNCTION_NONE)break;if (funType DRSTREAM_FUNCTION_STATUS) {READING_DLL_DATA cifs.Next();std::string status READING_DLL_DATA;READING_DLL_DATA cifs.Next();std::string value READING_DLL_DATA;OS::get_singleton()-print([Pipe.Read] funType %d status %s, value %s\n, funType, status.c_str(), value.c_str());}} while (true);//ConnectToServer(FPipeServerName);}
}bool TCbwPipe::WriteDllStream(TDllStream os, int timeout) {DWORD dwWrite;int len os.Size 1;BYTE *data os;if (!WriteFile(g_hNamedPipe, data, len, dwWrite, NULL)) {OS::get_singleton()-print([Pipe.Error] 写入数据失败:%d\n, GetLastError());delete data;return false;}delete data;return true;
}bool TCbwPipe::ConnectToServer(std::string pipeServerName) {FPipeServerName pipeServerName;if (g_hNamedPipe ! INVALID_HANDLE_VALUE g_hNamedPipe ! NULL)CloseHandle(g_hNamedPipe);g_hNamedPipe INVALID_HANDLE_VALUE;const char *t_PipeName pipeServerName.c_str();return CreateNamePipeC(t_PipeName);
}
实现过程没费劲就是编译费劲。一直提示相应功能没有实现。原来godot是用scons什么工具编译的需要配置路径什么的。为省事避免琢磨scons我把CbwPipe两个文件放在已有目录下就OK了。
GDScript支持
在源码中增加了功能肯定是希望在godot项目中使用比如用GDScript编写脚本时可用
在CharGPT指导下完成这个功能还算顺利。核心是与ClassDB打交道
class DllStream : public Object {GDCLASS(DllStream, Object);TDllStream stream;public:DllStream();DllStream *rewind();DllStream * write(const Variant **p_args, int p_argcount, Callable::CallError r_error);void send_pipe();
};DllStream::DllStream() {ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, write, DllStream::write, MethodInfo(write));ClassDB::bind_method(D_METHOD(rewind), DllStream::rewind);ClassDB::bind_method(D_METHOD(send_pipe), DllStream::send_pipe);
}DllStream * DllStream::write(const Variant **p_args, int p_argcount, Callable::CallError r_error) {for (int i 0; i p_argcount; i) {print_line(DllStream::write(, i 1, /, p_argcount, : type , p_args[i]-get_type_name(p_args[i]-get_type()), , value , *p_args[i]);switch (p_args[i]-get_type()) {case Variant::BOOL:stream bool(p_args[i]);break;case Variant::INT:stream int(*p_args[i]);break;case Variant::FLOAT:stream float(*p_args[i]);break;case Variant::STRING:stream String(*p_args[i]).ptr(); // todo: char32_t的处理break;}}return this;
}DllStream* DllStream::rewind() {stream.Rewind();return this;
}void DllStream::send_pipe() {TCbwPipe::get_singleton()-WriteDllStream(stream);
}在godot启动过程中直接自动发一些管道信息
std::string pipeName String2std(p);
OS::get_singleton()-is_pipe_allowed TCbwPipe::get_singleton()-ConnectToServer(pipeName);
TDllStream dsSet, dsGet;
dsSet DRSTREAM_FUNCTION_SET MainForm Caption godot 标题 Command by DrGraph ioFinish;
dsGet DRSTREAM_FUNCTION_GET CurrentForm Caption ioFinish;
TCbwPipe::get_singleton()-WriteDllStream(dsSet);
TCbwPipe::get_singleton()-WriteDllStream(dsGet);
在DrGraph软件中接收到管道数据 GDScript注册
为了在GDScript中使用还需要注册类名
GDREGISTER_CLASS(DllStream);
在Script编辑器中就可以出现代码提示了 相应功能调用 Godot工程运行后在界面中操作以触发相应代码功能 使用触发后在Godot软件中可看到输出 DrGraph软件中同步收到管道信息 达到效果。还有一点小问题中文乱码应该是编解码问题有空再处理一下。