如何调用一个返回类型为char*或string的由C/C++编写的DLL中导出的函数?

huangapple go评论108阅读模式
英文:

How to invoke an exported function from DLL written in C/C++ which return type is char* or string?

问题

我们设计的C/C++ DLL就像这样:

WIN32_DLL_EXPORT int FnRetInt(int i)
{
   ....
   return 32 ;
} 

WIN32_DLL_EXPORT char* FnRetString()
{
   return "THIS IS A TEST STRING" ;
}

当我们在Go中使用syscall调用这两个函数时:

hd:=syscall.NewLazyDLL(dll_path)
proc:=hd.NewProc(dll_func_name)
ret:=proc.Call()

我们发现:

FnRetInt正常工作,但FnRetString没有。proc.Call的返回类型是uintptr,我们如何将其更改为我们想要的类型(例如:char*或string)?

英文:

We designed C/C++ DLL just like this:

WIN32_DLL_EXPORT int FnRetInt(int i)
{
   ....
   return 32 ;
} 

WIN32_DLL_EXPORT char* FnRetString()
{
   return "THIS IS A TEST STRING" ;
}

when we invoke these two functions in Go by using syscall:

hd:=syscall.NewLazyDLL(dll_path)
proc:=hd.NewProc(dll_func_name)
ret:=proc.Call()

we found:

FnRetInt worked ok, but FnRetString didn't. proc.Call return type is uintptr, how can we change it to the type we wanted (for exsample: char* or string)?

答案1

得分: 2

一个uintptr是Go语言中表示指针的类型。你可以使用unsafe包将其转换为unsafe.Pointer,然后可以将unsafe.Pointer转换为任何Go指针类型。所以你可以像这样做:

str := (*uint8)(unsafe.Pointer(ret))

来获取一个*uint8类型的指针。

英文:

A uintptr is a Go type that represents a pointer. You can use the unsafe package and convert it to unsafe.Pointer, and then you can convert an unsafe.Pointer into any Go pointer type. So you could do something like

str := (*uint8)(unsafe.Pointer(ret))

to get a *uint8 back.

答案2

得分: 1

看一下syscall.Getwd的Windows实现http://code.google.com/p/go/source/browse/src/pkg/syscall/syscall_windows.go#323。它与你的问题不同:

  • 它将缓冲区传递给dll,而不是从dll接收它;
  • 数据是uint16s(Microsoft WCHARs),而不是uint8s;
  • GetCurrentDirectory告诉我们结果字符串的长度,而你的示例可能希望你在末尾搜索0;

但应该给你足够的线索。

Alex

英文:

Look at syscall.Getwd windows implementation http://code.google.com/p/go/source/browse/src/pkg/syscall/syscall_windows.go#323. It is different from your problem:

  • it passes buffer to the dll, instead of receiving it from dll;
  • the data is uint16s (Microsoft WCHARs), instead of uint8s;
  • GetCurrentDirectory tells us how long resulting string is going to be, while your example, probably, expects you to search for 0 at the end;

But should give you enough clues.

Alex

huangapple
  • 本文由 发表于 2012年9月13日 09:33:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/12398261.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定