当前位置: 首页 > news >正文

网站建设分金手指专业一网页已改版

网站建设分金手指专业一,网页已改版,海报设计图片简单,免费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软件中同步收到管道信息 达到效果。还有一点小问题中文乱码应该是编解码问题有空再处理一下。
http://www.huolong8.cn/news/385281/

相关文章:

  • 网站大学报名官网入口网站建设就问山东聚搜网络f
  • 制作网站的公司注册资本要多少网站建立需要什么
  • 网站开发价格明细有无广告销售版本"有广告免费无广告收费"网站
  • 苏州建设监督网站漫画网站源码
  • 做一个中英文网站多少钱网站站点是什么?如何创建站点?
  • 全景图网站怎么做域名注册查询工具
  • 公司做网站主机是什么用途wordpress ydg theme
  • 怎么自己做购物网站网站设计制作ihanshi
  • 凡科网怎么建网站织梦模板栏目页文件在哪
  • 罗湖网站制作多少钱网站怎么做登录界面
  • 有哪些做海报好的网站wordpress多用户小程序商城
  • 做ui什么图库网站好呀网络服务器搭建与配置
  • 怎么制作网站步骤wordpress分享到微信二维码
  • 中卫网站设计厂家装修设计灵感网站
  • 网站建设开发心得汉中市网站建设公司
  • 免费cms网站静态手机网站基础
  • 一个在线做笔记的网站买网站服务器吗
  • 岳阳网站网站建设哈什么网一个网站做ppt
  • 怎样让网站优化的方式网站开发各个文件
  • 哪个平台做网站比较好免费 网站 手机
  • 阿里企业网站托管ui设计培训机构有用吗
  • 404 not found网站航空港建设局网站
  • 济南网站建设方案报价长沙seo网络公司
  • 有口碑的中山网站建设广东住房和城乡建设厅网站造价
  • 美工宝盒网站网站开发三大框架
  • 厦门旋挖建筑公司网站获取网站目录下所有文件
  • 做网站绿标wordpress app主题
  • 做网站制作的公司php免费源码网站
  • ps做网站标签乡村门户网站建设
  • 食品网站建设方案上海建设行政主管部门政务网站