How to use a C library from D? - c

Today I heard about the D programming and that it is compatible to C code. Nevertheless I haven't found any information on whether it is possible to use C libraries like GTK or PortAudio from D?
If it is possible, could you explain how to do this?

It is possible to call C libraries from D. What you need to do is to convert the C header files to D. For the most part this is pretty straightforward, and there is a hard-to-use command-line tool to help automate the process. It's never really worked for me on anything but toy examples, but it could be a good start to see the kind of transformations that need to be done. Just put a snippet you're having trouble translating into a header by itself and see what htod does with it.
The biggest problem you'll usually encounter is creative use of the C preprocessor. Some things can be turned into version() statements in D, but not all.
As for actually compiling and linking with the code, on unix-like platforms I think you can compile and link in the C code using GCC. On Windows you either have to compile the C files using DMC and link with DMD. Or you can compile the C code into a DLL using any compiler capable of that, and then to link with DMD you need to make a DMD-compatible import lib out of the DLL. This can be done using the implib tool found in the free Basic Utilities Package available from DigitalMars.
There are also a lot of these header translations have already been done. It's useful to browse the Bindings project of Dsource first, or ask on the digitalmars D newsgroups first before embarking on something big like translating GTK headers. A lot of popular libraries like GTK have already been wrapped (e.g. here: GTKD)

D code can be linked with C object files, and can interact with C dlls, but you'll need to generate a D module from the C header file you want to use. The official D website has a guide for doing that very thing.

Popular alternative is to load the library during the run-time. Here is an example how to load libpng and call a libpng function:
module libpngtest;
import std.stdio;
import core.sys.posix.dlfcn;
alias uint function() png_access_version_number_t;
int main() {
auto lib = dlopen("libpng.so".ptr, RTLD_LAZY | RTLD_LOCAL);
if (lib is null) {
writeln("EEEK!");
writeln(to!string(dlerror()));
return -1;
} else {
writeln("WOOT!");
auto png_access_version_number = cast(png_access_version_number_t)dlsym(lib, "png_access_version_number");
writeln(png_access_version_number());
}
if (dlclose(lib) == 0) {
return 0;
} else {
return -1;
}
} // main() function
// compile: dmd libpngtest.d -L-ldl
// run: ./libpngtest
Use the DPaste to test it: http://www.dpaste.dzfl.pl/917bc3fb

You need to write C bindings.
This answer explain how.

Take a look at http://dsource.org
There are many projects that might help you to get start with

Related

Using 3rd Party C files with C Lion, a beginner perspective

I am in despair for a simple explanation to a simple problem.
I made a program in java that I need to recode in C for performance reasons. So I learned how to program in C. The problem is that C standard libraries do not contain collections (why????) such as a hashtables, treesets, etc. So I found this: https://github.com/srdja/Collections-C.
I use CLion on windows, I know well about coding but NOTHING about compiling, CMake, Linux, etc. My question is: I want to use those external source files my project, why is that so hard ? The tutorial on the link provided above tells me to use Linux command lines and stuff that I don't understand. Online I find stuff about telling me to add commands into CMakelist, none of these work for diverse reasons. I can't even copy all the .c and .h into my project because "they are not part of the project". So can anyone tell me how to make this simple code work ?
#include <stdio.h>
#include "hashtable.h"
int main() {
Hashtable *table;
hashtable_new(&table); //this is a function that creates the new hashtable in the source code of Collections-C
return 0;
}
By the way, because I think it's the same problem, how can I have subdirectories in my project so that I can put my header files away to keep the project tree tidy? I tried to add add_subdirectories($/include) to my CMakelist.txt
I am expecting people telling me that there are many similar questions already, but none of those I found is clear to me.
Thank you if you have the patience to explain this to me.
Henri
This is for C++, but it should work for your C code. In this example, it's defining where to find the OpenSSL and Google Test headers, and how to link with the Google Test library and the OpenSSL library (which is in C, as it turns out):
cmake_minimum_required(VERSION 3.5)
project(stackexample)
set(CMAKE_CXX_STANDARD 11)
find_library(GTest required)
include_directories(${GTEST_INCLUDE_DIRS} /usr/include/openssl)
set(
SOURCE_FILES
StackExample.cpp
StackExample.h
)
add_executable(stackexample ${SOURCE_FILES})
target_link_libraries(stackexample -lgtest -lssl -lcrypto pthread)
Collections-C appears to have an installer, so you would
List the path to its installed headers in the include_directories line
List its installed library in the target_link_libraries line
The solution was to build the library then do stuff with CMake. I followed this tutorial.

What is the easiest way to parse an INI File in C?

There are some similar questions about C++, Java and C# so now my question is about C. If I have this config file
[BBDD]
user=**
password=***
database=***
IPServidor=*
port=3***
[Device]
dev=8
Temperatura=5=1001
Humedad=7=1002
Link=8=1003
Volt=9=1004
[Device]
dev=10
Temperatura=5=1012
Humedad=7=1013
Link=8=1014
Volt=9=1015
what is the best way to read the values of Device. I am a linux user. I used glib but I had some problems because there is the same key (Device) so it returns me as the tutorial says only the values of the last Device array. Also Boost as I know has libraries for C++, libconfig also I think is not used for this kind of config files. Finally iniparser has a difficult installation guide for me. Do you think that some solutions like sscanf, fprintf are good?
Finally iniparser has a difficult installation guide for me. Do you think that some solutions like sscanf, fprintf are good?
The iniparser may have a difficult installation, but that's a small tradeoff for code that already works, has already been tested, and handles cases that you haven't thought of.
What problems are you having with using iniparser? I just tried it. I first did make in the iniparser directory, and the code was built. To use the library, I did the following:
gcc test.c ./libiniparser.a
This was because I had created the test program in the same directory as the library. When you include iniparser.h in C++, make sure to do the following:
extern "C"
{
#include "src/iniparser.h"
}

CppUTest not working

I am trying to rewrite some legacy C code and would like to have some tests in place before actually starting the rewrite. FOr this I took a look at CppUTest and tried a sample application consisting of a header file chrtostr.h, an implementation file chrtostr.c and a test file called test_chrtostr.c which contents is listed bellow:
#include <CppUTest/CommandLineTestRunner.h>
#include "chrtostr.h"
TEST_GROUP(chrtostr)
{
}
TEST(chrtostr, test_chrtostr)
{
CHECK_EQUAL(chrtostr('n'), "sfsdfds");
}
int main(int ac, char **av)
{
return CommandLineTestRunner::RunAllTests(ac, av);
}
And the corresponding Makefile.am:
AUTOMAKE_OPTIONS = foreign
CPPUTEST_HOME = ./cpputest
CFLAGS = -g -Wall -I$(CPPUTEST_HOME)/include
LDFLAGS = -L$(CPPUTEST_HOME)/lib -lCppUTest
bin_PROGRAMS = chrtostr test_chrtostr
chrtostr_SOURCES = chrtostr.c chrtostr.h main.c
test_chrtostr_SOURCES = test_chrtostr.c
The issue is that each time I try to run make I get the following traceback which doesn't actually help me too much: http://pastebin.com/BK9ts3vk
You should probably start by getting one of the demos going. You could see how CppUTest is intended to be used with C. My book, Test-Driven Development for Embedded C, will help you get started too. The first few chapters use a C-Only test harness. Later examples use CppUTest (I'm one of the authors of CppUTest). I also describe the advantages of a C++ test harness for C.
James
p.s. - for more information on CppUTest, look at CppUTest.org
That test driver is written in C++. You'll need to compile that as C++, so rename your file to .cpp and make sure g++ is called to drive the compile/link (rather than gcc).
Unfortunately, the "HelloWorld" example in CppUTest is undocumented and while the Appendix in "Test Driven Development for Embedded C" lists only 11 condition checks, I am finding that there are a lot more undocumented helper functions (all pretty much undocumented). I wouldn't recommend CppuTest unless you are trying to understand the concepts of TDD.
I would look for more of a commercial product or you are going to pick up a lot of bad TDD habits or get really frustrated and just move on.
I was just looking at this again. There were a few problems with your code. C++ errors don't always help clear them up.
I added comment before the things i fixed.
#include "CppUTest/TestHarness.h"
//The test file is c++. YOu have to tell it when you are linking to C code
extern "C"
{
#include "chrtostr.h"
}
//A test group needs to have a ';' after it. Under the hood, this macro
//create a base class for the test cases of the same name
TEST_GROUP(Chrtostr)
{
};
//CHECK_EQUAL uses ==. STRCMP_EQUAL actually compares c-strings
TEST(Chrtostr, wrong)
{
STRCMP_EQUAL(chrtostr('n'), "sfsdfds");
}

find out the origin of function calls

I wonder if there is a software that can help us determine all possible origins of a function call.
For example:
/* in file f1.c */
int f1() {
x_func();
}
/* in file f2.c */
int f2() {
x_func();
}
If we want to trace the origin of all function calls to x_func(), the output will be:
f1.c:f1()
f2.c:f2()
This is very useful when reading the source code.
All answers are appreciated. Thank in advance :D
cscope can help here
If you want to the this at runtime any debugger will be able to do that: just place a breakpoint within x_func and print the stack trace any time it pauses.
Doxygen will do that for you (with pictures!).
Also many IDEs also incorporate such capabilities Visual Studio for example will generate textual call graphs as well as having a "find all references" search. You can do this with the free VC++ Express Edition, the project need not be a VC++ project to use its code navigation features, just create a makefile project and add the header file paths to the preprocessor settings.
Tagfile programs, such as ctags and etags, do this. They're written to work with editors rather than to be specifically human readable. Emacs's M-. key looks things up in the tagfile.

Convert C function to Objective C or alternative way to include C library?

Background:
I'm new to Objective-C and I've never touched C before. I'm trying to include a C library in my iPhone/iPod Touch project and I could not successfully compile the library's source code using the included instructions, so I've resorted to including the .h and .c files in Xcode. The library is for Hebrew Dates and corresponding Jewish Holidays. It can be found here: http://sourceforge.net/projects/libhdate/
I cannot seem to import the .c files into my implementation files. I can import the .h files though. When I try to use #import "file.c", where file.c is a file that is in XCode, it doesn't work. Why not?
I've considered just writing the functions over in Objective-C, albeit only my needed functions and not the whole library.
How can I make the following C function work in Objective-C? Are there other things that need to be included/re-coded/compiled? How so? I am almost certain something is missing, but I'm not sure what.
Code:
int hdate_get_omer_day(hdate_struct const * h)
{
int omer_day;
hdate_struct sixteen_nissan;
hdate_set_hdate(&sixteen_nissan, 16, 7, h->hd_year);
omer_day = h->hd_jd - sixteen_nissan.hd_jd + 1;
if ((omer_day > 49) || (omer_day < 0))
omer_day = 0;
return omer_day;
}
So... should I be converting it, or trying somehow to compile to an appropriate format and how so? (I don't know what format a static library should be in, by the way, or if it should be static... - I'm so lost here....)
I appreciate the help!
You don't import implementation files. You just compile them alongside and include the appropriate header so that your code knows about the function and datatype declarations.

Resources