如何从用C / C ++编写的DLL调用导出的函数,其返回类型为char *或string?

我们像这样设计C / C ++ DLL:</ p>

   WIN32_DLL_EXPORT int FnRetInt(int i)
{
....
返回32;
}

WIN32_DLL_EXPORT char * FnRetString()
{
返回“这是一个测试字符串”;
}

</ code> </ pre>

,当我们使用syscall在 Go </ code>中调用这两个函数时:</ p>

   hd:= syscall.NewLazyDLL(dll_path)
proc:= hd.NewProc(dll_func_name)
ret:= proc.Call()
</ code> </ pre>

我们发现:</ </ p>

FnRetInt </ code>正常,但 FnRetString </ code>无效。 proc.Call </ code>返回类型为 uintptr </ code>,如何将其更改为所需的类型(例如,示例:char *或字符串)?</ p>
</ DIV>

展开原文

原文

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)?

2个回答



查看syscall.Getwd Windows实现 http://code.google.com/p/go/source/browse/src/pkg/syscall/syscall_windows.go#323 < / A>。 不同于您的问题:</ p>


  • 它将缓冲区传递给dll,而不是从dll接收缓冲区; </ li>
  • 数据为uint16s (Microsoft WCHAR),而不是uint8s; </ li>
  • GetCurrentDirectory告诉我们结果字符串将持续多长时间,而您的示例可能希望您在末尾搜索0; </ li>

    </ ul>

    但是应该给你足够的线索。</ p>

    Alex </ p>
    </ div>

展开原文

原文

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



uintptr </ code>是表示指针的Go类型。 您可以使用 unsafe </ code>包并将其转换为 unsafe.Pointer </ code>,然后可以将 unsafe.Pointer </ code>转换为任何Go指针类型。 因此,您可以执行以下操作</ p>

  str:=(* uint8)(unsafe.Pointer(ret))
</ code> </ pre>

< p>取回 * uint8 </ code>。</ p>
</ div>

展开原文

原文

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.

donglu3087
donglu3087 您可以做的是构造一个[] byte切片,并开始从* uint8中复制字节,直到遇到NUL,然后可以将其转换为字符串。
接近 8 年之前 回复
duankong8998
duankong8998 是的,那是一个指针值。 大概它指向一系列字符,带有NUL终止符。 Cgo提供了一个函数C.GoString(),该函数接受一个* C.char并返回一个字符串,但是如果您不使用Cgo,那么它将需要更多的工作才能将其转换为可用的字符串。
接近 8 年之前 回复
douzhajie7168
douzhajie7168 为您的codez:它得到:获取结果:0x30f7c01c如何从这一点获取值?
接近 8 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐