Two names for the same function

僤鯓⒐⒋嵵緔 提交于 2021-01-29 06:04:13

问题


I need two instances of the same function (not just alias). One thing that definitely works is

void writedata(union chip *tempchip, unsigned char *datapos, int datanum)
{
   blahblah
}

void writestring(union chip *tempchip, unsigned char *datapos, int datanum)
{
   writedata(tempchip, datapos, datanum);
}

This is kind of silly, because the second just passes parameters to the first. So I tried to be "smart" and make a pointer

void writedata(union chip *tempchip, unsigned char *datapos, int datanum)
{
   blahblah
}

void (* writestring)(union chip *, unsigned char *, int) = writedata;

which on using returns segmentation error. Why is the second method not working?

EDIT: I am calling both functions from Python via ctypes:

writedata = parallel.writedata
writedata.argtypes = [devpointer, POINTER(c_ubyte), c_int]

writestring = parallel.writestring
writestring.argtypes = [devpointer, c_char_p, c_int]

because I want to supply both strings and byte arrays as the second argument.


回答1:


I think you just want to pass data different was to a single function, such as this other question you asked. The solution is to use a c_void_p on the Python side to accept different kinds of pointers. The C code will receive the pointer and treat it as unsigned char *.

Here's a sample DLL which just focuses on the problem:

test.c

#include <stdio.h>

__declspec(dllexport)
void func(unsigned char *datapos, size_t length)
{
    for(int i = 0; i < length; ++i)
        printf("%02hhx ",datapos[i]);
    printf("\n");
}

test.py

from ctypes import *

dll = CDLL('./test')
_func = dll.func
_func.argtypes = c_void_p,c_size_t
_func.restype = None

def func(data):
    _func(data,len(data))

test1 = b'\x01\x02\x03'
test2 = (c_ubyte*3)(1,2,3)

func(test1)
func(test2)

Output:

01 02 03
01 02 03



回答2:


I think there's a solution that might work for you. It achieves the effect you were after, but it does it from the linker rather than your C source.

My assumption is that you're building a shared library for use with Python. If that assumption is correct, then you can do the following.

Let's say your shared library is called libclib1.so, and that you're doing something like the following to create it:

gcc -shared mysource.o -o libclib1.so

You can change this to add an alias for your function as follows:

gcc -shared mysource.o -Xlinker -defsym=writestring=writedata -o libclib1.so

This will create a new symbol, writestring, with the same value as writedata.

Of course, if you have a bunch of these, doing this on the command line could be a problem. But there's a solution for that as well. All you need to do is create a file with all your alias options in it. For example, you could call it aliases.txt. It would look like:

-Xlinker -defsym=writestring=writedata

The file could contain as many options as you like, each on their own line. Then you can change your shared library link command to:

gcc -shared mysource.o @aliases.txt -o libclib1.so

This will pick up the options from aliases.txt, adding all of your needed aliases to libclib1.so.




回答3:


Two instances of the same function: (I think the OP wanted two entry points, or labels or symbols , though)


inline static unsigned f0( unsigned aa, unsigned bb)
{
return aa %bb + bb %aa;
}

#if WANT_MAGIC /* not needed, anyway */
#define MAGIC  __attribute__ ((noinline)) 
#else
#define MAGIC  /**/
#endif

unsigned MAGIC f1( unsigned aa, unsigned bb)
{
return f0( aa, bb);
}

unsigned MAGIC f2( unsigned aa, unsigned bb)
{
return f0( aa, bb);
}

You could make the f1 and f2 functions different: accepting different argument types, and casting appropiately.



来源:https://stackoverflow.com/questions/64817912/two-names-for-the-same-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!