c++ dll 中函数原型
long AVSS_SetActiveDecoder ( HWND hwnd , LPCTSTR url ,LPCTSTR options , char * codecType
LONG handleID, LONG paramID , VARIANT paramValue )其中 paramValue.vt = VT_LPSTR paramValue.pcVAL 为 LPCTSTR 类型c# 中的调用
[Dllimport(dllpath),Charset=Charset.Ansi,CallingConvention = CallingConvention.Cdecl]
public static Int32 AVSS_SetActiveDecoder (IntPtr hwnd, string url ,string options, string
codecType , Int32 handleID, Int32 paramID, object paramValue)
运行VS 程序报错: 值不在预期的范围内 现在可以肯定(IntPtr hwnd, string url ,string options, string codecType , Int32 handleID, Int32 paramID) 这几个参数的赋值是没有问题的 主要是paramValue 的问题我在c#中定义了一个结构体
[StructLayout(LayoutKind.Sequential,Pack = 1 )]
public struct paramValue
{
```public int vt; //这里因为VT_LPSTR是VC6底层的数据类型,是固定的整数值30
public string pcVal;
}
paramValue pv = new paramValue ();
pv.vt = 30;
pv.pcVal = "********";我觉得这么调用应该是没有问题的,搜了不少网页,说“值不在预期范围”还是参数赋值的问题,我看了很多网上说关于VARIANT 和object赋值的帖子,通过结构体赋值应该也是可以的吧 ,本人一直用C# ,对VARIANT 这种类型的C++变量不是很熟悉,向大家请教一下解决问题的办法,很急!先谢过了。c#c++
long AVSS_SetActiveDecoder ( HWND hwnd , LPCTSTR url ,LPCTSTR options , char * codecType
LONG handleID, LONG paramID , VARIANT paramValue )其中 paramValue.vt = VT_LPSTR paramValue.pcVAL 为 LPCTSTR 类型c# 中的调用
[Dllimport(dllpath),Charset=Charset.Ansi,CallingConvention = CallingConvention.Cdecl]
public static Int32 AVSS_SetActiveDecoder (IntPtr hwnd, string url ,string options, string
codecType , Int32 handleID, Int32 paramID, object paramValue)
运行VS 程序报错: 值不在预期的范围内 现在可以肯定(IntPtr hwnd, string url ,string options, string codecType , Int32 handleID, Int32 paramID) 这几个参数的赋值是没有问题的 主要是paramValue 的问题我在c#中定义了一个结构体
[StructLayout(LayoutKind.Sequential,Pack = 1 )]
public struct paramValue
{
```public int vt; //这里因为VT_LPSTR是VC6底层的数据类型,是固定的整数值30
public string pcVal;
}
paramValue pv = new paramValue ();
pv.vt = 30;
pv.pcVal = "********";我觉得这么调用应该是没有问题的,搜了不少网页,说“值不在预期范围”还是参数赋值的问题,我看了很多网上说关于VARIANT 和object赋值的帖子,通过结构体赋值应该也是可以的吧 ,本人一直用C# ,对VARIANT 这种类型的C++变量不是很熟悉,向大家请教一下解决问题的办法,很急!先谢过了。c#c++
public struct paramValue
{
```public int vt; //这里因为VT_LPSTR是VC6底层的数据类型,是固定的整数值30
public string pcVal;
}
paramValue pv = new paramValue ();
pv.vt = 30;
pv.pcVal = "********";
变体类型Variant,能够在运行期间动态的改变类型。变体类型能支持所有简单的数据类型,如整型、浮点、字符串、布尔型、日期时间、货币及OLE自动化对象等,不能够表达Object Pascal对象。!
但在这个网上查的结果,调用变体类型参数转换只能是object类型啊,你有成功调用含variant类型dll的实例吗?
VT_LPSTR不常见。不改的话,C#方面就要自己传VARIANT结构。另,你的paramValue定义有误。private void button1_Click(object sender, EventArgs e)
{
// Marshal帮你传VARIANT,但字符串将作为BSTR
Show(this.Handle, "hello world");
Show(this.Handle, 1234);
Show(this.Handle, new object[] { "nihao", 5678, "abcd" });
}
private void button2_Click(object sender, EventArgs e)
{
// 自己传VARIANT结构
Variant v = new Variant()
{
vt = 30, //VT_LPSTR
byref = Marshal.StringToHGlobalAnsi("Bonjour"),
};
Show(this.Handle, v);
Marshal.FreeHGlobal(v.byref);
}
[DllImport("MyDll.dll", CallingConvention=CallingConvention.Cdecl)]
extern static void Show(IntPtr hWnd, object variant);[DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl)]
extern static void Show(IntPtr hWnd, Variant variant);[StructLayout(LayoutKind.Sequential)]
struct Variant
{
public short vt;
private short reserved1, reserved2, reserved3;
public IntPtr byref;
}C++测试代码:// mydll.cpp
#include "stdafx.h"
#include <atlstr.h>
#include <Windows.h>CStringW GetString(const VARIANT& v)
{
CStringW result;
if (v.vt == VT_BSTR)
{
result = v.bstrVal;
}
else if(v.vt == VT_LPSTR)
{
result = (LPSTR)v.byref;
}
else if (v.vt == VT_I4)
{
result.Format(L"%d", v.intVal);
}
else if (v.vt == VT_ARRAY | VT_VARIANT && v.parray->cDims == 1)
{
VARIANT* pArray = (VARIANT*)v.parray->pvData;
int count = v.parray->rgsabound[0].cElements;
for(int i=0; i < count; i++)
{
result.AppendFormat(L"%s ", GetString(*(pArray + i)));
}
}
return result;
}extern "C" _declspec(dllexport) void Show(HWND hWnd, VARIANT v)
{
MessageBoxW(hWnd, GetString(v), L"From C++ dll", MB_OK);
}
Marshal.GetNativeVariantForObject
tempRet = pcurrentPlugin->fncSetParam(connectRet,paramID,paramValue);就这两句用到了,没什么特殊的
因为最早variant是vba(ole/com的前身)中的类型,只有vt_bstr,这个特性也保留到ole/com作为传递字符串的类型。bstr就是前面是4字节的字符串长度,后面跟unicode的字符串,没有\0结束符,这跟c++中的lpstr的不一样的地方。
这个参数在c++如何构造的