如何用SWIG封装可接收Lua字符串表的C++函数?
The error you're seeing (Error in readTable expected 2..2 args, got 1) happens because the built-in typemaps in typemaps.i only handle primitive types like float for the array+length pattern. There's no default typemap for std::string[], so SWIG doesn't know how to convert your single Lua table argument into the two C++ parameters (std::string values[], int len).
Here's how to fix this with custom SWIG typemaps:
Step 1: Define Custom Typemaps for std::string Array
Add these typemaps to your .i file to handle converting a Lua table to a C++ std::string array and length. We'll also add a cleanup typemap to avoid memory leaks.
%module your_module_name // Include necessary headers for string handling %include <std_string.i> %include <typemaps.i> // Custom typemap to convert Lua table to std::string array + length %typemap(in) (std::string values[], int len) { // Verify input is a Lua table if (!lua_istable(L, $input)) { SWIG_exception(SWIG_TypeError, "Expected a table for string array input"); } // Get table length (Lua tables are 1-indexed, lua_rawlen gives correct count) $2 = lua_rawlen(L, $input); // Allocate memory for the std::string array $1 = new std::string[$2]; // Iterate over table elements and populate the array for (int i = 0; i < $2; ++i) { lua_pushinteger(L, i + 1); lua_gettable(L, $input); // Ensure each element is a string if (!lua_isstring(L, -1)) { delete[] $1; // Clean up before throwing exception SWIG_exception(SWIG_TypeError, "All table elements must be strings"); } // Convert Lua string to std::string $1[i] = lua_tostring(L, -1); lua_pop(L, 1); // Remove the string from Lua stack } } // Cleanup the allocated array after function execution to prevent leaks %typemap(freearg) (std::string values[], int len) { delete[] $1; } // Apply the custom typemap to your function's parameter signature %apply (std::string values[], int len) {(std::string values[], int len)}; // Declare and expose your C++ function %{ #include <iostream> #include <string> static void readTable(std::string values[], int len) { for (int i = 0; i < len; ++i) { std::cout << "VALUE : " << values[i] << std::endl; } } %} static void readTable(std::string values[], int len);
Step 2: Compile and Test
Compile your SWIG module as you did for the float version (e.g., swig -lua -c++ your_interface.i, then compile the generated C++ file with your compiler).
In Lua, you can now call the function exactly like the float version:
readTable({"hello", "swig", "lua"})
Why This Works
- The
intypemap handles the conversion from a single Lua table to the two required C++ parameters: it validates the input, calculates the table length, allocates astd::stringarray, and populates it with converted Lua strings. - The
freeargtypemap ensures we clean up the allocated array after the function runs, preventing memory leaks. - The
%applydirective tells SWIG to use these custom typemaps for any function matching the(std::string values[], int len)parameter pattern.
This should resolve the argument count error and let you pass Lua string tables to your C++ function seamlessly.
内容的提问来源于stack exchange,提问作者Zack Lee

