CGSTATUS __stdcall BeginCGCard(int nDevice, HCG *pHandle);
CGSTATUS __stdcall CGSetVideoStandard(HCG hcg, VIDEO_STANDARD mode);
像这种在本地dll中需要传递参数为指针跟结构体的、
在CLR/C++中需要怎样写、
12 个解决方案
#1
指针可以用ref,比如C++的参数是int *,C#可以传入ref int。
具体可以参考帮助文档“.Net Framework高级开发”-“互操作性”-“与非托管代码交互操作”-“使用非托管DLL函数”
具体可以参考帮助文档“.Net Framework高级开发”-“互操作性”-“与非托管代码交互操作”-“使用非托管DLL函数”
#2
现在还在CLR/C++这里啊、还没到C#应用那一层吧、不知道你说的是什么意思
#3
CLR\C++语法和C++是一样的,该怎么传就怎么传
#4
看这个http://wenku.baidu.com/view/5126f84b2b160b4e767fcf85.html?st=1
#5
把你的HCG和VIDEO_STANDARD的定义(如果有头文件最好)在C++/CLR中引入,有源文件的话直接调用,否则用DllImport导入函数定义。之后就直接调用那两个函数,没任何障碍,C++/CLR中是可以直接传递C++中的结构的,但是函数的输出CGSTATUS类型,你需要封装成C#可识别的托管类型才行,否则C#无法调用。
#6
已经引入了、现在在CLR/C++中我传入相同的参数即可?结构体不需要再定义了?
#7
能把这两函数写出来看看么、需要怎样写
#8
亲、这不是我想要的、项目要求不能用dllimport
#9
能引入就简单了,你把C++/CLR后面的CLR去掉,其实就是C++而已,因此调用那两个函数是不受限制的,接下来要处理的就是输入输出问题,你要给C#访问,那么就需要定义一个CLR的类,类中定义方法,方法的输入和输出参数虽然可以直接用HCG和VIDEO_STANDARD,但是别这样,你要是直接用了那参数,C#就只能看到函数定义,调用不起来,参数和返回值必须重新定义为C#能识别的托管类型,然后函数内部将托管类型的值赋给非托管类型,仅此而已。
#10
对了、我就是到这一步不知道怎么做了、类中定义方法、怎么定义
namespace CGVideoWrapper {
public ref class CLRWrapper
{
private:
CGVideo * CGVideoCpppro;
public:
CLRWrapper(void);
~CLRWrapper(void);
// TODO: 在此处添加此类的方法。
};
}
#11
extern "C" __declspec(dllexport) void dowork(byte* from,void* to,int length);
void dowork(byte* from,void* to,int length)
{
byte* tmp = (byte*)to;
for(int i = 0;i<length;i++)
{
*tmp = *from;
tmp++;
from++;
}
}
namespace CGVideoWrapper {
public ref class CLRWrapper
{
public:
generic <typename T> where T : value class
static T Read(array<Byte>^ data)
{
T value;
pin_ptr<System::Byte> src = &data[0];
pin_ptr<T> dst = &value;
byte* a = (byte*)src;
void* b = (void*)dst;
dowork(a,b,sizeof(T));
return value;
}
};
}
看下这段例子,dowork是C++定义的一个方法,用于将from指针中的内容复制到to指针里面去,实现对象的拷贝,第三个参数是需要拷贝的长度。显然这个方法不能被C#直接调用,那么我就用这个Read方法封装下,那个Read方法的输入参数是array<Byte>^ data,为托管类型字节数组,输出为结构体T(泛型),作用是将字节转换为对应的结构体。为了能够使用那个dowork进行操作,函数Read内部对输入参数处理,转换为byte* a,输出的托管对象value也进行处理,得到它的指针,这样就可以用dowork进行操作了,最后返回的是托管对象value,整个操作对Read方法的外部来说,看不到任何非托管类型,非托管类型在内部进行了处理。
#12
懂了、TKS
#1
指针可以用ref,比如C++的参数是int *,C#可以传入ref int。
具体可以参考帮助文档“.Net Framework高级开发”-“互操作性”-“与非托管代码交互操作”-“使用非托管DLL函数”
具体可以参考帮助文档“.Net Framework高级开发”-“互操作性”-“与非托管代码交互操作”-“使用非托管DLL函数”
#2
现在还在CLR/C++这里啊、还没到C#应用那一层吧、不知道你说的是什么意思
#3
CLR\C++语法和C++是一样的,该怎么传就怎么传
#4
看这个http://wenku.baidu.com/view/5126f84b2b160b4e767fcf85.html?st=1
#5
把你的HCG和VIDEO_STANDARD的定义(如果有头文件最好)在C++/CLR中引入,有源文件的话直接调用,否则用DllImport导入函数定义。之后就直接调用那两个函数,没任何障碍,C++/CLR中是可以直接传递C++中的结构的,但是函数的输出CGSTATUS类型,你需要封装成C#可识别的托管类型才行,否则C#无法调用。
#6
已经引入了、现在在CLR/C++中我传入相同的参数即可?结构体不需要再定义了?
#7
能把这两函数写出来看看么、需要怎样写
#8
亲、这不是我想要的、项目要求不能用dllimport
#9
能引入就简单了,你把C++/CLR后面的CLR去掉,其实就是C++而已,因此调用那两个函数是不受限制的,接下来要处理的就是输入输出问题,你要给C#访问,那么就需要定义一个CLR的类,类中定义方法,方法的输入和输出参数虽然可以直接用HCG和VIDEO_STANDARD,但是别这样,你要是直接用了那参数,C#就只能看到函数定义,调用不起来,参数和返回值必须重新定义为C#能识别的托管类型,然后函数内部将托管类型的值赋给非托管类型,仅此而已。
#10
对了、我就是到这一步不知道怎么做了、类中定义方法、怎么定义
namespace CGVideoWrapper {
public ref class CLRWrapper
{
private:
CGVideo * CGVideoCpppro;
public:
CLRWrapper(void);
~CLRWrapper(void);
// TODO: 在此处添加此类的方法。
};
}
#11
extern "C" __declspec(dllexport) void dowork(byte* from,void* to,int length);
void dowork(byte* from,void* to,int length)
{
byte* tmp = (byte*)to;
for(int i = 0;i<length;i++)
{
*tmp = *from;
tmp++;
from++;
}
}
namespace CGVideoWrapper {
public ref class CLRWrapper
{
public:
generic <typename T> where T : value class
static T Read(array<Byte>^ data)
{
T value;
pin_ptr<System::Byte> src = &data[0];
pin_ptr<T> dst = &value;
byte* a = (byte*)src;
void* b = (void*)dst;
dowork(a,b,sizeof(T));
return value;
}
};
}
看下这段例子,dowork是C++定义的一个方法,用于将from指针中的内容复制到to指针里面去,实现对象的拷贝,第三个参数是需要拷贝的长度。显然这个方法不能被C#直接调用,那么我就用这个Read方法封装下,那个Read方法的输入参数是array<Byte>^ data,为托管类型字节数组,输出为结构体T(泛型),作用是将字节转换为对应的结构体。为了能够使用那个dowork进行操作,函数Read内部对输入参数处理,转换为byte* a,输出的托管对象value也进行处理,得到它的指针,这样就可以用dowork进行操作了,最后返回的是托管对象value,整个操作对Read方法的外部来说,看不到任何非托管类型,非托管类型在内部进行了处理。
#12
懂了、TKS