通过互操作接收字符串 [英] receiving strings through interop

查看:136
本文介绍了通过互操作接收字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法得到一个字符串从C代码我写了回信。

I'm having trouble getting a string back from some c code I wrote.

首先是一些一般unrealated背景资料:我想收到用户可读字符串从TAPI API一个TAPI TSP。我已经实现了一个半可行的TAPI解决方案依赖于驱动程序名称匹配存储的字符串,但想改变这种对您永久在线的ID,而不是工作,因为我们的一个客户有一个(阿尔卡特)PBX,可以拒绝工作的任何其他方式

First some generally unrealated background info: I'd like to receive the user readable string for a TAPI TSP from the TAPI API. I've implemented a semi workable TAPI solution relying on matching driver names to stored strings, but would like to change this to work on permanant line id's instead, as one of our customers has an (Alcatel) PBX that refuses to work any other way.

在C,我在我的头文件定义函数:

In C, I define the function in my header file as:

__declspec(dllexport) void GetDeviceName(long DeviceId, wchar_t* DeviceName);



该功能正是如此写的:

The function is written thusly:

__declspec(dllexport) void GetDeviceName(long DeviceId, wchar_t* DeviceName)
{
    //tapi code here...

    //copy the string to DeviceName
    wcscpy(DeviceName, (wchar_t*)((char *)devCaps + devCaps->dwLineNameOffset));
}



如上所述,这最终会做一些有用的东西,但现在我会。很高兴,如果ABC是摆在我的wchar_t * / StringBuilder的,我可以看到,在C#

As stated above, this will eventually do something useful but for now I'll be happy if abc is placed in my wchar_t*/StringBuilder and I can see that in C#.

在C#中,我定义的功能为:

In C# I define the function as:

    [DllImport("SBW.Tapi.TapiInterop.dll", CharSet = CharSet.Auto)]
    static extern void GetDeviceName(long DeviceId, StringBuilder DeviceName);



我定义设备名称作为一个StringBuilder,因为字符串是immuatable,我想的设备名称在C设置(这是由MS 推荐)。我还设置了返回类型为无效的渺茫希望,​​也影响了一些(见的这个获取的部分伪科学的解释)半有益的单品

I define DeviceName as a StringBuilder because a string is immuatable and I want the DeviceName to be set in C (This is recommended by MS). I also set the return type to void on the slim hope that that also affects something (see this semi helpful mono article for a partial pseudo scientific explanation).

和调用它这样:

StringBuilder name = new StringBuilder();
name.EnsureCapacity(100);
long n = 0;
GetDeviceName(n, name);



我在我的调试器附加到正在运行的进程,设置断点,并通知在C代码,不知怎的StringBuilder的是变态的,并提供给非托管代码作为一个空指针。

I attach my debugger to the running process, set a breakpoint, and notice in the C code that somehow the StringBuilder is perverted and is provided to the unmanaged code as a null pointer.

这是AccessViolationException随后在C#中抛出。

An AccessViolationException is subsequently thrown in C#.

什么乱子?

删除参数长帮助。我能ABC添加到我的C.参数设备名称我想要变长但是!我究竟做错了或不安,从而通过让有那么长的参数,以强制实施崩溃?

removing the long parameter helps. I'm able to add "abc" to my DeviceName parameter in C. I want that long variable however! What am I doing wrong or upsetting so as to force a crash by having that long parameter there?

推荐答案

在32位平台上是8字节(64位)宽的.NET和4字节(32位)宽的本机代码。你需要改变你这样的P / Invoke方法:

On 32 bits platforms long is 8 bytes (64 bits) wide in .NET and 4 bytes (32 bits) wide in native code. You need to change your P/Invoke method like this:

[DllImport("SBW.Tapi.TapiInterop.dll", CharSet = CharSet.Auto)]
static extern void GetDeviceName(int DeviceId, StringBuilder DeviceName);



这样,C# INT 和C 对32位平台的宽度相同。

This way, C# int and C long have the same width on 32 bits platforms.

这篇关于通过互操作接收字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆