Streamline and improve std::string typemaps
Avoid unnecessary heap allocations, just use temporary variables. Actually update the string parameters passed by pointer/non-const reference. This requires the pointers passed to actually be non-const, so update the C-specific unit test runme to use a char buffer instead of a literal string. Also simplify the code copying the string contents to just use strdup() (if there are ever any platforms where this POSIX functions is not available, we could just define it ourselves once instead of using strlen() + malloc() + memcpy() manually twice).
This commit is contained in:
parent
628e2cf6d2
commit
aacc930023
2 changed files with 49 additions and 38 deletions
|
|
@ -6,7 +6,8 @@
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
char *myComposedString = c_backend_cpp_natural_std_string_myStringAppend("World, ", "Hello!");
|
char buf[] = "World, ";
|
||||||
|
char *myComposedString = c_backend_cpp_natural_std_string_myStringAppend(buf, "Hello!");
|
||||||
|
|
||||||
assert(myComposedString);
|
assert(myComposedString);
|
||||||
assert(strcmp(myComposedString, "World, Hello!") == 0);
|
assert(strcmp(myComposedString, "World, Hello!") == 0);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,31 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
%fragment("SwigStrInOut", "header") {
|
||||||
|
class SwigStrInOut {
|
||||||
|
std::string str_;
|
||||||
|
char* ptr_;
|
||||||
|
size_t len_;
|
||||||
|
public:
|
||||||
|
void init(char* ptr) {
|
||||||
|
ptr_ = ptr;
|
||||||
|
if (ptr_) {
|
||||||
|
str_ = ptr_;
|
||||||
|
len_ = str_.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string* str() { return &str_; }
|
||||||
|
|
||||||
|
~SwigStrInOut() {
|
||||||
|
if (ptr_) {
|
||||||
|
memcpy(ptr_, str_.c_str(), len_);
|
||||||
|
ptr_[len_] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|
||||||
// use "const string &" typemaps for wrapping member strings
|
// use "const string &" typemaps for wrapping member strings
|
||||||
|
|
@ -9,49 +34,34 @@ namespace std {
|
||||||
|
|
||||||
class string;
|
class string;
|
||||||
|
|
||||||
%typemap(ctype) string "char *"
|
%typemap(ctype) string, const string & "const char *"
|
||||||
%typemap(ctype) string * "char *"
|
%typemap(ctype) string * "char *"
|
||||||
%typemap(ctype) string & "char *"
|
%typemap(ctype) string & "char *"
|
||||||
%typemap(ctype) const string & "char *"
|
|
||||||
|
|
||||||
%typemap(in) string {
|
%typemap(in) string %{
|
||||||
if ($input) {
|
if ($input)
|
||||||
$1.assign($input);
|
$1 = $input;
|
||||||
}
|
%}
|
||||||
else {
|
|
||||||
$1.resize(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
%typemap(in) const string &, string *, string & {
|
%typemap(in) const string & (std::string temp) %{
|
||||||
if ($input) {
|
if ($input)
|
||||||
$1 = new std::string($input);
|
temp = $input;
|
||||||
}
|
$1 = &temp;
|
||||||
else {
|
%}
|
||||||
$1 = new std::string();
|
|
||||||
$1->resize(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
%typemap(freearg) const string &, string *, string & {
|
%typemap(in, fragment="SwigStrInOut") string * (SwigStrInOut temp), string & (SwigStrInOut temp) %{
|
||||||
if ($1)
|
temp.init($input);
|
||||||
delete $1;
|
$1 = temp.str();
|
||||||
}
|
%}
|
||||||
|
|
||||||
%typemap(out) string {
|
// Note that we don't support strings with embedded NULs, as there is no way to
|
||||||
const char *str = cppresult.c_str();
|
// return their length to C code anyhow.
|
||||||
size_t len = strlen(str);
|
%typemap(out) string %{
|
||||||
$result = (char *) malloc(len + 1);
|
$result = strdup(cppresult.c_str());
|
||||||
memcpy($result, str, len);
|
%}
|
||||||
$result[len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
%typemap(out) const string &, string *, string & {
|
%typemap(out) const string &, string *, string & %{
|
||||||
const char *str = cppresult->c_str();
|
$result = strdup(cppresult->c_str());
|
||||||
size_t len = strlen(str);
|
%}
|
||||||
$result = (char *) malloc(len + 1);
|
|
||||||
memcpy($result, str, len);
|
|
||||||
$result[len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue