Closed. This question is off-topic。它当前不接受答案。
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。
                        
                        3天前关闭。
                                                                                            
                
        
我正在尝试在Go中使用Google/re2

我做了这样的CPP函数:

extern "C" bool PartialMatch (std::string text, std::string pattern, int* number)
{
    return RE2::PartialMatch(text, pattern, number);
}


完整代码:pal.cpp

pal.h:

#include <string>
extern "C" bool PartialMatch (std::string text, std::string pattern, int* number);


然后,我用以下命令编译它:g++ pal.cpp pal.h -fPIC -std=gnu++14 -ggdb -O0 -fdata-sections -D"NDEBUG=1" -D"RELEASE=1" -ffunction-sections -Wl,-gc-sections -shared "-lpthread" -Wl,-soname,"pal.so" -o "pal.so"

然后,我像这样使用它:

package main

/*
#cgo CFLAGS: -I .
#cgo LDFLAGS: -lstdc++
*/
import "C"
import (
   "fmt"
   "github.com/rainycape/dl"
)

func TestPal()  {
   var PluginObj    *dl.DL
   var PartialMatch func(string, string, *int) int
   pattern := "(ciao) me"
   text := "ciao me"
   var number int

   //var printC   func(word *C.char) bool
   fmt.Print("hello\n")
   PluginObj, err := dl.Open("../pal.so", 0x01000)
   if err == nil {
      err = PluginObj.Sym("PartialMatch", &PartialMatch)
      if err != nil {
         fmt.Print("plugin lookup failed: " + err.Error())
      } else {
         fmt.Println(PartialMatch(pattern, text, &number))  // Expecting "1"
      }
   } else {
      fmt.Print("error %v\n", err)
   }
   return
}
func main() {
   TestPal()
}


当我构建并运行此代码时,它输出以下错误:
pal.so: undefined symbol: ZN3re23RE23Arg9parseintEPKcmPv

看起来由于此行而发生错误:
return RE2::PartialMatch(text, pattern, number);

去不懂RE2::

因为当我删除PartialMatch函数并使用isPalindrome函数对其进行测试时,它可以正常工作!

extern "C" int isPalindrome(char* word)
{
    int ret = 1;

    char *p = word;
    int len = strlen(word);
    char *q = &word[len-1];

    for (int i = 0 ; i < len ; ++i, ++p, --q)
    {
        if (*p != *q)
        {
            ret = 0;
        }
    }

    return ret;
}


我怎样才能解决这个问题?

最佳答案

该符号在libre2.so中定义。

顺便说一句,要使用Golang中的PartialMatch,必须将其定义为C函数,例如:

int PartialMatch (const char *text, const char *pattern, int *number);


并在pal.cpp源中:

extern "C" int PartialMatch (const char *text, const char *pattern, int *number)
{
    return RE2::PartialMatch(text, pattern, number);
}


我不确定,您真的要手动加载吗?

package main

/*
#include <stdlib.h>
int PartialMatch (const char *text, const char *pattern, int *number);
#cgo LDFLAGS: -L ${SRCDIR} -Wl,-rpath,${SRCDIR} -lpal -Wl,-rpath,/usr/local/lib -lre2
*/
import "C"
import (
    "fmt"
    "unsafe"
)

func Re2PMatch(text, pattern string) (ok bool,number int) {
    pat := C.CString(pattern)
    txt := C.CString(text)
    n := C.int(0)
    ok = C.PartialMatch(txt,pat,&n) != 0
    C.free(unsafe.Pointer(pat))
    C.free(unsafe.Pointer(txt))
    number = int(n)
    return
}

func main() {
    pattern := "(o.e)"
    text := "this is just one test"
    fmt.Println(Re2PMatch(text,pattern))
}


如果要手动加载pal.so,请尝试在pal.so编译字符串中添加-lre2 -Wl,-no-neased。它将迫使pal.so引用libre2.so.0,而libre2必须通过dlopen调用来加载。至少我希望如此。

LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH ldd pal.so
    linux-vdso.so.1 (0x00007ffe56bfc000)
    libre2.so.0 => /usr/local/lib/libre2.so.0 (0x00007f453a201000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f4539e78000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4539ada000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f45398c2000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f45394d1000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f45392b2000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f453a691000)

09-25 19:00