CGO undefined reference in included files - go

Wraping up OpenJtalk in Go, files are successfully included and types are referenced without an issue, but functions trigger an undefined reference error.
jtalk.go:
package main
// #cgo CFLAGS: -I/home/vagrant/open_jtalk/njd [...etc]
/*
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
// Main headers
#include "mecab.h"
#include "njd.h"
#include "jpcommon.h"
#include "HTS_engine.h"
// Sub headers
#include "text2mecab.h"
#include "mecab2njd.h"
#include "njd_set_pronunciation.h"
#include "njd_set_digit.h"
#include "njd_set_accent_phrase.h"
#include "njd_set_accent_type.h"
#include "njd_set_unvoiced_vowel.h"
#include "njd_set_long_vowel.h"
#include "njd2jpcommon.h"
*/
import "C"
type Open_JTalk struct {
mecab C.Mecab each of these struct references are fine
njd C.NJD
jpcommon C.JPCommon
engine C.HTS_Engine
}
func (open_jtalk *Open_JTalk) Open_JTalk_initialize() {
C.Mecab_initialize(&open_jtalk.mecab) // when any function is called the error happens
C.NJD_initialize(&open_jtalk.njd)
C.JPCommon_initialize(&open_jtalk.jpcommon)
C.HTS_Engine_initialize(&open_jtalk.engine)
}
func main() {
}
And the weird part is that those same functions are declared right after the types:
mecab.h
// line 1584
typedef struct _Mecab{
char **feature;
int size;
mecab_t *mecab;
} Mecab;
BOOL Mecab_initialize(Mecab *m);
Project webpage: http://open-jtalk.sourceforge.net/

You need to add cgo linker options (LDFLAGS) with the path to and the name of your library. e.g.
// #cgo CFLAGS: -Iyour-include-path
// #cgo LDFLAGS: -Lyour-library-path -lyour-library-name-minus-the-lib-part

Related

cgo on macOS - unknown type name NSString

In a go code i have following code:
/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -L./ ${SRCDIR}/test.dylib -framework Foundation
#include "./test.h"
#include <stdlib.h>
#include <stdio.h>
#import <Foundation/Foundation.h>
#import <Foundation/NSString.h>
*/
import "C"
test.h has a struct with NSString
On building the go code it shows
error: unknown type name 'NSString' NSString nspath,
can someone guide what's wrong here since i have included appropriate objective C libraries and headers.
Not running OSX/iOS, but looking at github, it looks like at least some developers wrap objective-c code in the cgo preamble inside a typical C function.
This looks like a particularly good example:
/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Foundation
#import <Foundation/NSBundle.h>
#import <Foundation/NSString.h>
#include <stdlib.h>
#include <string.h>
const char *assets_zip_path() {
NSString *path = [[NSBundle mainBundle] pathForResource: #"aaaaxy" ofType: #"dat"];
const char *data = [path UTF8String];
if (data == NULL) {
return NULL;
}
return strdup(data);
}
*/
import "C"
func openAssetsZip() (*os.File, error) {
pathCStr := C.assets_zip_path()
...
You also may already find the bindings you need in the go/mobile package.

error: expected ‘)’ before ... (header file constructor)

I have this header file for a class Dictionary
#ifndef DICTIONARY_H
#define DICTIONARY_H
#include <string>
#include <vector>
#include <unordered_set>
class Dictionary {
public:
Dictionary(string wordFile);
bool contains(const string& word) const;
vector<string> get_suggestions(const string& word) const;
private:
unordered_set<string> words;
};
#endif
and I'm getting the error "error: expected constructor, destructor, or type conversion before ‘(’ token Dictionary::Dictionary(string wordFile) ". In the .cpp file it looks like this:
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <algorithm>
#include "word.h"
#include "dictionary.h"
#include <unordered_set>
#include <string>
Dictionary::Dictionary(string wordFile) {
string str;
ifstream input(wordFile);
while (getline(input, str)) {
words.insert(str);
}
}
bool Dictionary::contains(const string& word) const {
unordered_set<string>::const_iterator got = words.find(word);
if(got == words.end()){
return false;
}
return true;
}
vector<string> Dictionary::get_suggestions(const string& word) const {
vector<string> suggestions;
return suggestions;
}
I have no idea what's wrong... I come from a Java background and I'm having some trouble getting accustomed to writing in C++ and fixing these errors.
The original error was because you didn't qualify string in the header file:
Dictionary(string wordFile);
That should be:
Dictionary(std::string wordFile);
(and similarly for the other uses of string and unordered_map in the header).
You'll have the same problem in the .cpp file, but you can solve it there by simply adding using namespace std; to the top of the file, after all the #include directives. (You should not put using namespace in header files, or before including headers files, as it can have unwanted consequences and confuse later headers).

how to include linux kernel header files

I am attempting some Linux kernel development.
I have a problem in including a header file sched.h (which exists in the path /usr/src/linux-3.12.26/kernel/sched, not in /usr/src/linux-3.12.26/include/linux ).
But when I "sudo make -C /usr/src/linux-3.12.26/ M=$(pwd) modules" I got the error "fatal error: kernel/sched/sched.h: doesn't exist"
Here is my code:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/percpu.h>
#include </usr/src/linux-3.12.26/kernel/sched/sched.h>
int __init init_current(void){
int cpu_num=0;
struct task_struct *p;
for(cpu_num=0;cpu_num<8;cpu_num++)
{
p=curr_task(cpu_num);
printk(KERN_ALERT "current task on cpu %d is %d\n", cpu_num, p->pid);
}
return 0;
}
void __exit exit_current(void)
{
printk(KERN_ALERT "FINISHED!\n");
}
MODULE_LICENSE("GPL");
module_init(init_current);
module_exit(exit_current);
There may be some errors in the code. My intention is to get the current running process in different cores.
#Santosh A .Thanks for continuing concerning my puzzle.After I changed the Makefile in /usr/src/linux-3.12.26/(see my answer above,it may not be normative,but work ),the headers I include can be found.Then I get another problem. Here is my code:
#include <linux/init.h>
#include <linux/module.h>
//#include <linux/sched.h>
#include <linux/percpu.h>
#include <sched/sched.h>
static int __init init_current(void){
int cpu_num=0;
extern struct task_struct *p;
struct rq *q;
extern struct rq * cpu_rq(int);
for(cpu_num=0;cpu_num<8;cpu_num++)
{
q=cpu_rq(cpu_num);
p=q->curr;
printk(KERN_ALERT "current task on cpu %d is %d\n", cpu_num, p->pid);
}
return 0;
}
static void __exit exit_current(void)
{
printk(KERN_ALERT "FINISHED!\n");
}
MODULE_LICENSE("GPL");
module_init(init_current);
module_exit(exit_current);
Here is error info:
/home/wison/code/current/current.c: In function ‘init_current’:
kernel/sched/sched.h:539:23: error: expected identifier or ‘(’ before ‘&’ token
#define cpu_rq(cpu) (&per_cpu(runqueues, (cpu)))
^
/home/wison/code/current/current.c:11:28: note: in expansion of macro ‘cpu_rq’
extern struct rq * cpu_rq(int);

Application crashes says : Access violation reading location 0xbaadf04d

I m doing project in opencv... i m getting error like this
"Unhandled exception at 0x775a15ee in touch.exe: 0xC0000005: Access violation reading location 0xbaadf04d."
the code is
using namespace std;
#include "stdafx.h"
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include "math.h"
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <sstream>
int main(int argc, char* argv[]){
//declerations
CvCapture *frame=0;
IplImage *image=0;
cvNamedWindow( "Image taken", CV_WINDOW_AUTOSIZE );
frame=cvCreateCameraCapture(2);
frame=cvCreateCameraCapture(2);
image = cvQueryFrame(frame);
cvShowImage("Image taken", image);
cvWaitKey(0);
return 0;
}
Try replacing
frame=cvCreateCameraCapture(2);
with
frame=cvCreateCameraCapture(-1);
if (!frame) {
puts("Couldn't detect a camera.");
return(1);
}

Boost serialization polymorphic register(export) not working across files

I am using boost::serialization in my project. The project is large, and serializes my objects in several places. According to the documentation here, I should export my class with two separated step.
BOOST_EXPORT_KEY() in .h file, witch contains the declaration.
BOOST_EXPOET_IMPLEMENT() in .cpp file, witch contains the instantiation(definition) of the exporting.
hier.h the class hierarchy, there are 3 classes in the hierarchy.
/*
B <---+--- D1
|
+--- D2
*/
#include <boost/serialization/base_object.hpp>
class B {
public:
virtual ~B() {}
template < typename Ar >
void serialize(Ar& ar, const int) {
}
} ;
class D1 : public B {
public:
virtual ~D1() {}
template < typename Ar > void serialize(Ar& ar, const int) {
boost::serialization::base_object<B>(*this);
}
} ;
class D2 : public B {
public:
template < typename Ar > void serialize(Ar& ar, const int) {
boost::serialization::base_object<B>(*this);
}
virtual ~D2() {}
} ;
#include <boost/serialization/export.hpp>
BOOST_CLASS_EXPORT_KEY(B);
BOOST_CLASS_EXPORT_KEY(D1);
BOOST_CLASS_EXPORT_KEY(D2);
And a hier.cpp contains the implementation:
#include <boost/serialization/export.hpp>
#include "hier.h"
BOOST_CLASS_EXPORT_IMPLEMENT(D1);
BOOST_CLASS_EXPORT_IMPLEMENT(D2);
And a main.cpp use the serialization:
#include <iostream>
#include <sstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
#include "hier.h"
int main(int argc, char* argv[])
{
B* d1 = new D1();
B* d2 = new D2();
std::ostringstream os;
boost::archive::text_oarchive oa (os);
oa & d1 & d2;
}
It compiled without any problem, but run it will cause:
terminate called after throwing an instance of 'boost::archive::archive_exception'
what(): unregistered class - derived class not registered or exported
Which means the derived class is not registered, means the registration in the hier.cpp is not working. But that is really strange, because:
If I register implementation is both main.cpp and hier.cpp, it issue duplicated definition while linking. Means the registration in hier.cpp is OK and is exposed into the linkers visibility., otherwise there will be no duplicated definition error.
If I register implementation only in main.cpp, it runs OK.
I am really confused in that situation. Any comment and suggestion is appreciated. Thanks in advance.
Before calling BOOST_CLASS_EXPORT_* you should include the archives which you want to use. The maсro then adds specific serialize-functions for the headers.
This means you should change your code in hier.cpp to the following:
#include <boost/serialization/export.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include "hier.h"
BOOST_CLASS_EXPORT_IMPLEMENT(D1);
BOOST_CLASS_EXPORT_IMPLEMENT(D2);
The code in hier.h changes accordingly:
#include <boost/serialization/export.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
BOOST_CLASS_EXPORT_KEY(B);
BOOST_CLASS_EXPORT_KEY(D1);
BOOST_CLASS_EXPORT_KEY(D2);
Sources:
Boost Serialization Documentation
PS:
I do not know if this is solving your problem, but I think it could be causing some trouble. I think it's worth a try.

Resources