|
私のプロジェクトでは、このメソッドを使用してDLL関数から文字列を返す: In my project, I use this method to return string from my DLL function:
方法/Method 1: [C++] #include <string.h> char *temp_buffer = nullptr;
// Join s1 + s2 as new string extern "C" __declspec(dllexport) const char* JoinString(const char* s1, const char* s2) { temp_buffer = new char[strlen(s1) + strlen(s2) + 1]; strcpy(temp_buffer, s1); strcat(temp_buffer, s2);
return temp_buffer; }
extern "C" __declspec(dllexport) bool FreeStringResource() { if (temp_buffer != nullptr) { delete[] temp_buffer; return true; } return false; } [/C++]
質問/Question 1:
私が知っているように、文字列リソースを解放するのはプロバイダの責任です。 だから私は、関数が "temp_buffer"を返した後、UWSCはこのデータに新しい文字列ベースを割り当てますが、この文字列リソースを解放しないと思います。 これは本当ですか? As I know, it is responsibility of the provider to free the string resource. So I think after the function returned "temp_buffer", UWSC will allocate new string base on this data, but it will not free this string resource. Is this true?
したがって、FreeStringResource()関数を以下のように呼び出すと、後で文字列を解放する方法が必要になります。 So, we need some how free the string later, as call the function FreeStringResource() like below:
[uws] DEF_DLL JoinString(string,string):string:uwsc.utils.dll DEF_DLL FreeStringResource():boolean:uwsc.utils.dll print JoinString("abc", "123") FreeStringResource() print JoinString("1111", "2222") FreeStringResource() [/uws]
上記の問題を回避するために、私は以下の方法を使用します: 上記の問題を回避するために、私は以下の方法を使用します:
方法/Method 2: [C++] #include <string> std::string temp_buffer; // Join s1 + s2 as new string extern "C" __declspec(dllexport) const char* JoinString(const char* s1, const char* s2) { temp_buffer = s1; temp_buffer += s2; return temp_buffer.c_str(); } [/C++] このメソッドを使用すると、文字列バッファはstd :: stringクラスによって管理され、リソースを手動で解放する必要はありません\ When using this method, the string buffer is managed by std::string class and we no need to manual free the resource anymore
質問/Question 2: 上記の関数はスレッドセーフではないので、複数のUWSCスレッドで使用することはできませんが、それは本当ですか? UWSCは各スレッドごとにDLLをロードしますか? 次の例はスレッドセーフではありません。コマンド "temp_buffer = s1;" 同時に2つのスレッドで呼び出すことができます The function above is still non-thread safe, so we can't use it in multiple UWSC thread, is that true? Does UWSC load DLL per each thread? The example below is not thread safe, because the command "temp_buffer = s1;" can be called in 2 thread at the same time: [uws] DEF_DLL JoinString(string,string):string:uwsc.utils.dll Thread F_Thread_1() Thread F_Thread_2()
procedure F_Thread_1() print JoinString("abc", "123") fend procedure F_Thread_2() print JoinString("1111", "2222") fend [/uws]
この関数はスレッドセーフなバージョンに修正できますが、後でリソースを解放する必要があります。 We can fix this function to thread safe version, but it still need to free the resource later:
方法/Method 3: [C++] #include <string.h> // Join s1 + s2 as new string extern "C" __declspec(dllexport) const char* JoinString(const char* s1, const char* s2, char* &temp_buffer) { temp_buffer = new char[strlen(s1) + strlen(s2) + 1]; strcpy(temp_buffer, s1); strcat(temp_buffer, s2);
return temp_buffer; }
extern "C" __declspec(dllexport) bool FreeStringResource(char *temp_buffer) { if (temp_buffer != nullptr) { delete[] temp_buffer; return true; } return false; } [/C++] [uws] DEF_DLL JoinString(string,string,var hwnd):string:uwsc.utils.dll DEF_DLL FreeStringResource(hwnd):boolean:uwsc.utils.dll Thread F_Thread_1() Thread F_Thread_2()
procedure F_Thread_1() dim hwnd print JoinString("abc", "123", hwnd) FreeStringResource(hwnd) fend procedure F_Thread_2() dim hwnd print JoinString("1111", "2222", hwnd) FreeStringResource(hwnd) fend [/uws]
現在、この関数を実装する別の方法が見つかりました: Currently, I found another way to implement the function:
方法/Method 4: [C++] #include <string.h> // Join s1 + s2 as new string extern "C" __declspec(dllexport) bool JoinString(const char* s1, const char* s2, char* result) { strcpy(result, s1); strcat(result, s2); return true; } [/C++] [uws] DEF_DLL JoinString(string,string,var string):boolean:uwsc.utils.dll dim s = "" print JoinString("abc", "123", s) print s [/uws]
質問/Question 3: 現時点では、上記の例はうまくいきますが、正しいとメモリが安全かどうかはわかりません。 例、strlen(s1)= strlen(s2)= 1000000、 "strcpy"と "strcat"はメモリからデータを書き出しますか? Currently, the above example work, but I'm not sure does it is correct and memory safe. Example, strlen(s1) = strlen(s2) = 1000000, does "strcpy" and "strcat" write data out of memory?
誰でも助けてくれてありがとう
|
No.4309 2017/08/16(Wed) 17:24:11
|
☆ Re: C++ DLL 関数から文字列を返す / vusd |
|
No.4310 2017/08/16(Wed) 23:31:24
|
|
☆ Re: C++ DLL 関数から文字列を返す / しゅん |
|
|
英語は苦手、、、。
Answer 1. true. Answer 2. I don't know. Perhaps, UWSC load DLL per each process. Answer 3. Not safe. Allocate memory with the UWSC script. [UWS] DEF_DLL JoinString(string,string,var string):boolean:uwsc.utils.dll dim s = FORMAT(CHR(0), 3 + 3 + 1) print JoinString("abc", "123", s) print s [UWS]
|
No.4315 2017/08/17(Thu) 14:00:31
|
|
☆ Re: C++ DLL 関数から文字列を返す / vusd |
|
|
あなたのお手伝いをありがとう
I try print pointer of global variable in DLL in multiple UWSC thread and all are the same value [C++] int global_var; extern "C" __declspec(dllexport) void* GetPointer() { return &global_var; } [/C++] [uws] DEF_DLL GetPointer():hwnd:uwsc.utils.dll PrintPointer() Thread PrintPointer() // same above Thread PrintPointer() // same above
procedure PrintPointer() print GetPointer() fend [/uws]
So, I think UWSC use the same DLL for each thread
|
No.4317 2017/08/18(Fri) 13:21:24
|
|
☆ Re: C++ DLL 関数から文字列を返す / vusd |
|
|
私はいくつかの私の理解の要約:
- Non-thread safe: Using method 1 or method 2 - Thread safe: + We know the size of output string: allocate memory with FORMAT() + use method 4 + We don't know the size of output string: use method 3
|
No.4318 2017/08/18(Fri) 13:29:01
|
|
☆ Re: C++ DLL 関数から文字列を返す / しゅん |
|
|
良いと思います。でも
If I were you, I'd do it like this.
[C++] #include <string.h> // Join s1 + s2 as new string extern "C" __declspec(dllexport) int JoinString(const char* s1, const char* s2, char* result, int size) { int n = strlen(s1) + strlen(s2) + 1; if (result && n > 0) { if (size >= n) { strcpy(result, s1); strcat(result, s2); } else { n = -1; } } return n; } [/C++] [uws] DEF_DLL JoinString(string,string,var string,int):int:uwsc.utils.dll dim s1="abc", s2="123", n = JoinString(s1, s2, NULL, 0) dim s = FORMAT(CHR(0), n) print JoinString(s1, s2, s, n) print s [/uws]
|
No.4321 2017/08/18(Fri) 17:08:39
|
|
☆ Re: C++ DLL 関数から文字列を返す / vusd |
|
|
はい、私はそれが良い方法だと思います I think this is a good method
I just notice that many current Windows API using this method, too (ex: GetWindowTextLength() -> GetWindowText)) )
|
No.4323 2017/08/18(Fri) 21:56:28
|
|