gpt4 book ai didi

c++ - 为 C++ 函数编写包装器以便在 C 代码中使用它们的挑战

转载 作者:太空宇宙 更新时间:2023-11-04 15:55:00 25 4
gpt4 key购买 nike

我现在正在为 C++ 函数编写包装器,这样它们就可以在 C 代码中使用。

想法是使用 g++ 编译 cpp 文件,使用 gcc 编译 c 文件,然后将它们链接在一起(!),但仅将那些需要的函数公开给 C 程序,方法是使它们在头文件中可用'test.h'(或者可能是 test.hpp?),像这样:

(请注意我如何不公开函数 'vector Tokenize(const string& str,const string& delimiters)')

test.h:

/* Header can be read by both C+ and C compilers, just the way we want! */
#ifndef TEST_H
#define TEST_H

#ifdef __cplusplus
extern "C" {
#endif

#if defined(__STDC__) || defined(__cplusplus)
extern int TokenizeC(const char* text, const char* delim, char ***output); /* ANSI C prototypes */
extern void reclaim2D(char ***store, unsigned int itemCount);
#endif

#ifdef __cplusplus
}
#endif

#endif /* TEST_H */

test.cpp:

#include <string>
#include <iostream>
#include <vector>

#include <assert.h>

#include "test.h"

using namespace std;

vector<string> Tokenize(const string& str,const string& delimiters)
{
vector<string> tokens;

string::size_type delimPos = 0, tokenPos = 0, pos = 0;

if(str.length() < 1) return tokens;

while(1)
{
delimPos = str.find_first_of(delimiters, pos);
tokenPos = str.find_first_not_of(delimiters, pos);

if(string::npos != delimPos)
{
if(string::npos != tokenPos)
{
if(tokenPos < delimPos) tokens.push_back(str.substr(pos,delimPos-pos));
else tokens.push_back("");
}
else tokens.push_back("");

pos = delimPos + 1;
}
else
{
if(string::npos != tokenPos) tokens.push_back(str.substr(pos));
else tokens.push_back("");
break;
}
}

return tokens;
}

int TokenizeC(const char* text, const char* delim, char ***output)
{
if((*output) != NULL) return -1; /* I will allocate my own storage, and no one tells me how much. Free using reclaim2D */

vector<string> s = Tokenize(text, delim);

// There will always be a trailing element, that will be blank as we keep a trailing delimiter (correcting this issue would not be worth the time, so this is a quick workaround)
assert(s.back().length() == 0); // This will be nop'ed in release build
s.pop_back();

(*output) = (char **)malloc(s.size() * sizeof(char *));

for(vector <string>::size_type x = 0; x < s.size(); x++)
{
(*output)[x] = strdup(s[x].c_str());

if(NULL == (*output)[x])
{
// Woops! Undo all
// TODO : HOW to test this scenario?

for(--x; x >= 0; --x)
{
free((*output)[x]);
(*output)[x] = NULL;
}

return -2;
}
}

return x; /* Return the number of tokens if sucessful */
}

void reclaim2D(char ***store, unsigned int itemCount)
{
for (int x = 0; itemCount < itemCount; ++x)
{
free((*store)[x]);
(*store)[x] = NULL;
}

free((*store));
(*store) = NULL;
}

poc.c:

#include <stdio.h>
#include "test.h"

int main()
{
const char *text = "-2--4--6-7-8-9-10-11-", *delim = "-";

char **output = NULL;

int c = TokenizeC(text, delim, &output);

printf("[*]%d\n", c);

for (int x = 0; x < c; ++x)
{
printf("[*]%s\n", output[x]);
}

reclaim2D(&output, c);

return 0;
}

你有没有发现什么不对?

对于初学者来说,当我运行这个程序时,我得到了“Unsatisfied code symbol '__gxx_personality_v0'”

谢天谢地,这里有一些东西:What is __gxx_personality_v0 for?

一旦我使用选项“-fno-exceptions -fno-rtti”运行 g++,输出现在失败并显示“Unsatisfied data symbol '_ZNSs4_Rep20_S_empty_rep_storageE'”

当然,这两种环境(编译环境 - HP-UX B.11.23 ia64 和运行二进制文件的环境 - HP-UX B.11.31 ia64)具有不同的库版本(但架构相同),而这不应成为错误的原因。

我还想测试标记为“//TODO : HOW to test this scenario?”的案例,但现在可以等一下。

有什么建议吗?

最佳答案

在链接时避免 undefined symbol 的最简单方法是使用 g++(而不是 gcc)进行链接。不过,您仍然可以使用 gcc 编译 .c 文件。

也请一次使用系统。如果您在同一系统(无论新旧系统)上运行所有 gcc 和 g++ 命令,链接错误可能会消失。

关于c++ - 为 C++ 函数编写包装器以便在 C 代码中使用它们的挑战,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/873356/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com