PyFile_Type replaced by ..? - c

I'm tyring to compile Yenc for Python 3.2. I noticed that gcc complained about a non-declared function PyString_Type, so I replaced it with its replacement PyBytes_Type as according to the documentation.
However, gcc also complained about an undeclared function called PyFile_Type. I googled a bit and found:
Python 3.x replaces the PyFile_Type extension type
with an abstract interface and specific implementation types.
Unfortunately it doesn't make any of this directly available
with a C level api.
source
I am by no means a C-programmer, which leaves me unable to solve this issue. What should I do to solve this?
Edit: output of compilation, _yenc.c
Thanks!

Simply put, PyFile_Type has been replaced by something not even remotely similar in Python 3, and you'll have to either modify the code yourself or wait for the maintainer to do that. If you're not a C programmer, it'll likely have to be the latter. The documentation states that rather than wrapping FILE*'s, Python 3 now wraps low-level I/O, in this case file descriptors and read()/write().

You can try using PyFileIO_Type, however you have to declare it before. (Original is located in _iomodule.h inside the Python sources):
extern PyTypeObject PyFileIO_Type;

Related

How can code that uses C FFI in Rust keep in sync with headers?

For code (typically crates) that use FFI to wrap C code,
how is it possible to keep Rust definitions and C headers in sync? Or ensure they are matching to begin with?
Are there tools to handle this or is it the responsibility of each developer to manually check this?
Update: To make this more concrete.
Is there a way to know when:
The member of a struct changes its type.
A function argument changes its type.
So that any mis-match with the Rust code can warn or fail to compile entirely?
I ran into a crash in a crate which I suspect is caused by API mismatch which remains reported but unfixed.
Solution 1: bindgen
The bindgen! module takes a C header file and generates Rust binding at compile time. Example from the bindgen documentation:
#![feature(plugin)]
#![plugin(bindgen)]
mod lua_bindings {
bindgen!("/usr/include/lua.h", link="lua", builtins=true)
}
It adds clang as a complexity to your code and relies on rust nightly. Unfortunately that makes your project heavy (dependency wise) and bound to rust nightly, but it helps your FFI bindings staying up to date, plus the cross architecture issue boils down to know where the header files are for each architecture.
In my experience bindgen works pretty good, it has some limitations so it won't work for all cases.
Solution 2: ctest
Another approach is taken by Libc. Libc consists basically of only FFI bindings for currently 18 supported architectures so it has a quite heavy requirement on correctness of FFI bindings.
In Libc the bindings are done by hand (often with the help of running bindgen in commandline) and then tested against the header files using https://github.com/alexcrichton/ctest
How it works is that you specify all the C headers you want to check against and then the library compares it against the extern fn definitions you specifies in your code and makes sure..
that all function signatures, constant values, struct layout/alignment, type size/alignment, etc, all match their C equivalent (quoted from the docs)
Throw travis into the mix and you can be sure your FFI bindings are correct for every code change across all supported architectures (have a look at libc's pull requests where every pull is automatically run through travis and lets the author correct all errors before the PR is merged).

ZeroMemory Function giving me errors in windows.h?

basically I am programming on a Mac, but I'm using source code from a group at school that had "windows.h" included.
I did some research and apparently there is no replica of that file for OSX.
I saw an answer on a thread here that said it was possible to make a "dummy" windows.h file and just insert whatever #includes or function prototypes I needed. To do this I just went online and got the functions I needed from some Microsoft directories.
I proceeded to do that and everything was working fine until the ZeroMemory function gave me errors.
So, inside of my dummy "windows.h" file:
void ZeroMemory([in] PVOID Destination,[in] SIZE_T Length);
I get these errors:
Expected parameter declarator
Use of undeclared identifier 'in'
Expected ')'
Now, I have googled the function and its errors and I keep finding a bunch of code that just has this line of code in it, which doesn't really help much.
What I need to know is where do I go from here? Am I doing the right thing by creating this "dummy" windows.h file? Or is there another way to get around using windows.h?
The link I found the answer to use a dummy windows.h file is here.
I appreciate all the input, so if you have anything on your mind, please throw it down! Thanks so much everyone!
After changing some of the code according to the comments:
void ZeroMemory(PVOID Destination, SIZE_T Length);
I get these errors:
Unknown type name PVOID
Unknown type name SIZE_T
I was thinking there may be some definitions I am missing but these are TYPE names, so they must be coming out of something like a Struct? Correct me if I'm wrong please? :D
If your header has [in] annotations then you grabbed the wrong file, most likely the IDL file instead of the actual header. In the header it should be _In_ instead, which will be an empty macro. In any case, you'll still have problems because you'll be missing the definitions of things like SIZE_T as you discovered. Unless you want to go and replace every dependency you hit, I'd recommend just replacing the calls themselves with your own versions. For ZeroMemory(p,s), you should be able to replace it trivially with memset(p,0,s). This of course assumes you're only using trivial functionality in the Windows header. If you're using actual platform-specific stuff like windowing, input, etc. then you'll probably just need to get a machine or VM running Windows.
It is a very bad habit that developers on the windows platform tend to fall into, including "windows.h" in simple applications that otherwise conform to standard C or C++.
The most correct option would be to encourage the other students / teacher? to only use standard c or c++ header files when writing their applications. This will ensure that they do not use any windows api specific functions.
You can, of course, create a windows.h, and inline in any trivial windows methods (As MooseBoys answers, ZeroMemory can be trivially implemented with memset) to be able to compile simple programs without altering them, but sooner or later some program is going to use a windows api with no easy or convenient standard C / C++ or CoreFoundation (On OSX, the equivalent framework to access windowing things) equivalent.

specific macro value in linux kernel module build

How to figure out a specific kernel macro value while building a kernel module.
There are lots of macro options and I wish to know the value assigned to a "specific macro" while building and the line number where it is defined.
I read about this a quite while ago...and I know it is quite possible.
for eg:
make modules SUBDIRS=drivers/net/e1000/
Now, in e1000 there is a macro used, HAVE_VLAN_IN_HW.
while building the module, I wish to know where exactly it is coming from (the macro definition and its value).?
Most of us use a Linux cross reference to find where functions, macros and variables are declared.
I should have googled it with better keywords like preprocessing output :
Here you find all relevant info:
http://kernelnewbies.org/FAQ/KernelCrossCompilation
Yet another facet of kernel compilation is that it helps you to generate preprocessed files. This is extremely useful when you suspect something could be wrong with your macros. In 2.4 days, we could get the command line and add -c option and redirect the result of gcc preprocessor to a file. In 2.6, it is built into the kernel. Here is how.
Say, I want to generate the preprocessor output for kernel/dma.c,
#make kernel/dma.i
Done. open kernel/dma.i to see what preprocessor did to dma.c
This is available for a module (not a part of kernel) too.

Error While Linking Multiple C Object files in Delphi 2007

I am new to delphi. I was trying to add C Object files in my Delphi project and link them directly since Delphi Supports C Object Linking. I got it working when i link a single Object file. But when i try to link multiple object files, i am getting error 'Unsatisfied forward or external declaration'. I have tried this in Delphi 2007 as well as XE.So what am i doing wrong here?
Working Code:
function a_function():Integer;cdecl;
implementation
{$Link 'a.obj'}
function a_function():Integer;cdecl;external;
end.
Error Code:
function a_function():Integer;cdecl;
function b_function();Integer;cdecl;
function c_function();Integer;cdecl;
implementation
{$LINK 'a.obj'}
{$LINK 'b.obj'}
{$LINK 'c.obj'}
function a_function():Integer;cdecl;external;
function b_function();Integer;cdecl;external;
function c_function();Integer;cdecl;external;
end.
As an aside, the article linked by #vcldeveloper has a good explanation of some of the common issues. The trick of providing missing C RTL functions in Pascal code is excellent and much quicker than trying to link in the necessary functions as C files, or even as .obj files.
However, I have a suspicion that I know what is going on here. I use this same approach but in fact have over 100 .obj files in the unit. I find that when I add new ones, I get the same linker error as you do. The way I work around this is to try re-ordering my $LINK instructions. I try to add the new obj files one by one and I have always been able, eventually, to get around this problem.
If your C files are totally standalone then you could put each one in a different unit and the linker would handle that. However, I doubt that is the case and indeed I suspect that if they really were standalone then this problem would not occur. Also, it's desirable to have the $LINK instructions in a single unit so that any RTL functions that need to be supplied can be supplied once and once only (they need to appear in the same unit as the $LINK instructions).
This oddity in the linker was present in Delphi 6 and is present in Delphi 2010.
EDIT 1: The realisation has now dawned on me that this issue is probably due to Delphi using a single pass compiler. I suspect that the "missing external reference" error is because the compiler processes the .obj files in the order in which they appear in the unit.
Suppose that a.obj appears before b.obj and yet a.obj calls a function in b() b.obj. The compiler wouldn't know where b() resides at the point where it needs to fixup the function call. When I find the time, I going to try and test if this hypothesis is at the very least plausible!
Finally, another easy way out of the problem would be to combine a.c, b.c and c.c into a single C file which would I believe bypass this issue for the OP.
Edit 2: I found another Stack Overflow question that covers this ground: stackoverflow.com/questions/3228127/why-does-the-order-of-linked-object-file-with-l-directive-matter
Edit 3: I have found another truly wonderful way to work around this problem. Every time the compiler complains
[DCC Error] Unit1.pas(1): E2065 Unsatisfied forward or external declaration: '_a'
you simply add, in the implementation section of the unit, a declaration like so:
procedure _a; external;
If it is a routine that you wish to call from Delphi then you clearly need to get the parameter list, calling conventions etc. correct. Otherwise, if it is a routine internal to the external code, then you can ignore the parameter list, calling conventions etc.
To the best of my knowledge this is the only way to import two objects that refer to each other in a circular manner. I believe that declaring an external procedure in this way is akin to making a forward declaration. The difference is that the implementation is provided by an object rather than Pascal code.
I've now been able to add a couple of more tools to my armory – thank you for asking the question!

Find header file that defines a C function

Shouldn't be hard, right? Right?
I am currently trawling the OpenAFS codebase to find the header definition of pioctl. I've thrown everything I've got at it: checked ctags, grepped the source code for pioctl, etc. The closest I've got to a lead is the fact that there's a file pioctl_nt.h that contains the definition, except it's not actually what I want because none of the userspace code directly includes it, and it's Windows specific.
Now, I'm not expecting you to go and download the OpenAFS codebase and find the header file for me. I am curious, though: what are your techniques for finding the header file you need when everything else fails? What are the worst case scenarios that could cause a grep for pioctl in the codebase to not actually come up with anything that looks like a function definition?
I should also note that I have access to two independent userspace programs that have done it properly, so in theory I could do an O(n) search for the function. But none of the header files pop out to me, and n is large...
Edit: The immediate issue has been resolved: pioctl() is defined implicitly, as shown by this:
AFS.xs:2796: error: implicit declaration of function ‘pioctl’
If grep -r and ctags are failing, then it's probably being defined as the result of some nasty macro(s). You can try making the simplest possible file that calls pioctl() and compiles successfully, and then preprocessing it to see what happens:
gcc -E test.c -o test.i
grep pioctl -C10 test.i
There are compiler options to show the preprocessor output. Try those? In a horrible pinch where my head was completely empty of any possible definition the -E option (in most c compilers) does nothing but spew out the the preprocessed code.
Per requested information: Normally I just capture a compile of the file in question as it is output on the screen do a quick copy and paste and put the -E right after the compiler invocation. The result will spew preprocessor output to the screen so redirect it to a file. Look through that file as all of the macros and silly things are already taken care of.
Worst case scenarios:
K&R style prototypes
Macros are hiding the definition
Implicit Declaration (per your answer)
Have you considered using cscope (available from SourceForge)?
I use it on some fairly significant code sets (25,000+ files, ranging up to about 20,000 lines in a file) with good success. It takes a while to derive the file list (5-10 minutes) and longer (20-30 minutes) to build the cross-reference on an ancient Sun E450, but I find the results useful.
On an almost equally ancient Mac (dual 1GHz PPC 32-bit processors), cscope run on the OpenAFS (1.5.59) source code comes up with quite a lot of places where the function is declared, sometimes inline in code, sometimes in headers. It took a few minutes to scan the 4949 files, generating a 58 MB cscope.out file.
openafs-1.5.59/src/sys/sys_prototypes.h
openafs-1.5.59/src/aklog/aklog_main.c (along with comment "Why doesn't AFS provide these prototypes?")
openafs-1.5.59/src/sys/pioctl_nt.h
openafs-1.5.59/src/auth/ktc.c includes a define for PIOCTL
openafs-1.5.59/src/sys/pioctl_nt.c provides an implementation of it
openafs-1.5.59/src/sys/rmtsysc.c provides an implementation of it (and sometimes afs_pioctl() instead)
The rest of the 184 instances found seem to be uses of the function, or documentation references, or release notes, change logs, and the like.
The current working theory that we've decided on, after poking at the preprocessor and not finding anything either, is that OpenAFS is letting the compiler infer the prototype of the function, since it returns an integer and takes pointer, integer, pointer, integer as its parameters. I'll be dealing with this by merely defining it myself.
Edit: Excellent! I've found the smoking gun:
AFS.xs:2796: error: implicit declaration of function ‘pioctl’
While the original general question has been answered, if anyone arrives at this page wondering where to find a header file that defines pioctl:
In current releases of OpenAFS (1.6.7), a protoype for pioctl is defined in sys_prototypes.h. But that the time that this question was originally asked, that file did not exist, and there was no prototype for pioctl visible from outside the OpenAFS code tree.
However, most users of pioctl probably want, or are at least okay with using, lpioctl ("local" pioctl), which always issues a syscall on the local machine. There is a prototype for this in afssyscalls.h (and these days, also sys_prototypes.h).
The easiest option these days, though, is just to use libkopenafs. For that, include kopenafs.h, use the function k_pioctl, and link against -lkopenafs. That tends to be a much more convenient interface than trying to link with OpenAFS libsys and other stuff.
Doesn't it usually say in the man page synopsis?

Resources