我正在开发一个使用 N-API(通过 napi)/node_api.h 与 Node.js 集成的 C++ 应用程序,其中我向 JavaScript 公开了 C++ 类和方法。具体来说,我有一个带有 CTF_player 对象向量的 TEAM 类,并且我想使用 GetPlayerName 方法获取玩家的姓名。
事情是这样的:
第一次调用 GetPlayerName 工作正常并返回预期结果。 但是,当我尝试再次调用相同的方法时,此后没有任何反应,也不会引发任何错误。 我怀疑内存管理或访问 CTF_player 对象向量(成员[索引])可能存在问题。
class CTF_player
{
private:
std::string name;
int score;
public:
// Constructor
CTF_player(const std::string &playerName, int playerScore)
: name(playerName), score(playerScore) {}
// Getter for name
std::string getName() const
{
return name;
}
// Getter for score
int getScore() const
{
return score;
}
// Setter for name
void setName(const std::string &newName)
{
name = newName;
}
// Setter for score
void setScore(int newScore)
{
score = newScore;
}
};
class TEAM
{
public:
std::vector<CTF_player> members;
std::string GetPlayerName(int index)
{
if (index < 0 || index >= members.size())
{
return ""; // Handle out-of-bounds case
}
return members[index].getName();
}
void addMember(const CTF_player &player)
{
members.push_back(player);
}
};
napi_value GetPlayerName(napi_env env, napi_callback_info info)
{
// Arguments parsing
size_t argc = 2;
napi_value args[2];
napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
TEAM *team;
napi_get_value_external(env , args[0] , (void**)&team);
int index;
status = napi_get_value_int32(env, args[1], &index);
std::string name = team->GetPlayerName(index);
napi_value js_name;
napi_create_string_utf8(env, name.c_str(), name.size(), &js_name);
return js_name;
}
let team1 = CreateCTF_TEAM("Team A", 1);
console.log("Team created:", GetTeamName(team1));
CreateCTFPlayer("bilal" , 1 , team1);
console.log("p1" , GetPlayerName(team1 , 0));
//after this the rest of the code is skipped
console.log("p1" , GetPlayerName(team1 , 0));
let team2 = CreateCTF_TEAM("Team B", 1);
console.log("Team created:", GetTeamName(team2));
第一次调用GetPlayerName后,后续调用都没有返回预期结果,第二次调用后似乎没有任何反应。 我怀疑这个问题可能与 std::string 处理或 JavaScript 调用之间 C++ 对象在内存中的管理方式有关。 内存管理(通过napi_create_external)或向量索引是否会导致问题? 如何确保对象在 Node.js 中的调用之间保持有效且可访问? 如果您能提供有关如何解决此问题或进一步研究的建议,我将不胜感激。
确保作为外部引用传递的
TEAM
对象已正确分配并保持有效。使用 napi_create_external
传递指针并关联终结器以防止意外释放:
napi_value CreateTeam(napi_env env, napi_callback_info info) {
TEAM* team = new TEAM(); // Allocate dynamically to ensure persistence
napi_value external;
napi_status status = napi_create_external(env, team, [](napi_env env, void* finalize_data, void* hint) {
TEAM* team = static_cast<TEAM*>(finalize_data);
delete team; // Clean up memory when the object is garbage collected
}, nullptr, &external);
if (status != napi_ok) {
napi_throw_error(env, nullptr, "Failed to create external TEAM object");
}
return external;
}