编写C ++函数的包装器的挑战,以便可以从C代码使用它们 [英] Challenges in writing wrappers for C++ functions so that they can be used from C code

查看:108
本文介绍了编写C ++函数的包装器的挑战,以便可以从C代码使用它们的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am now writing wrappers for C++ functions, such that they can be used from C code.

这个想法是使用g ++编译cpp文件,文件使用gcc,然后将它们链接在一起(!),但只暴露那些需要的功能,通过使它们在头文件'test.h'(或也许test.hpp?)可用的C程序,像这样:

The idea is to compile the cpp files using g++ and the c files using gcc, then link them together (!), but exposing ONLY those functions that are needed, to the C programs, by making them available in a header file 'test.h' (or maybe test.hpp?), like so:

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

(Note how I do not expose function 'vector Tokenize(const string& str,const string& delimiters)')


test.h:

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:

test.cpp:


b $ b

#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:

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;
}

您注意到错误吗?

对于初学者,当我运行这个程序时,我得到了不满意的代码符号'__gxx_personality_v0'

For starters, when I ran this program, I got "Unsatisfied code symbol '__gxx_personality_v0'"

谢谢,这里有一些东西:http://stackoverflow.com/questions/329059/what-is-gxxpersonalityv0-for

Thankfully, there is something here : http://stackoverflow.com/questions/329059/what-is-gxxpersonalityv0-for

一旦我使用选项-fno-exceptions -fno-rtti运行g ++,输出n

Once I ran g++ with options " -fno-exceptions -fno-rtti", the output n

推荐答案

以避免未定义的符号,而链接是链接到g ++(不是gcc)。你仍然可以用gcc编译你的.c文件。

The easiest way to avoid undefined symbols while linking is to link with g++ (not gcc). You can still compile your .c file with gcc, though.

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

Also please use system at a time. The link error may go away if you run all your gcc and g++ commands on the same system (no matter the old or the new one).

这篇关于编写C ++函数的包装器的挑战,以便可以从C代码使用它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆