问题
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 string
s and byte array
s 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