您的位置:首页 > 编程语言 > C语言/C++

Call C# Code from C++ and read an array of struct which contains strings

2009-06-12 14:50 786 查看

Introduction

My C++ code was trying to read an array of struct which contains string data in C# . To my surprise, I found that a struct array which contains only integer is very easy to get, but if you have a string in the array, you need to do some more thing. I searched in the google, and a lot of people talked about the same problem as they are getting the exception which says, �Old format or invalid type library�. But no where I was able to find the answer, so since I was able to solve the problem, I am publishing it.

Basic Ideas

I have a c# dll which contains a struct, lets say

public struct MyStruct

{

public string name;

public string surname;

public int age;

}

I have an interface which looks like this

public interface ITest

{

MyStruct[] GetData

{

get;

}

}

And my main class is

public class Test : ITest

{

MyStruct[] st = new MyStruct[2];

public Test()

{

st[0].name = "abc";

st[0].surname = "def";

st[0].age = 10;

st[1].name = "qwe";

st[1].surname = "rty";

st[1].age = 20;

}

public MyStruct[] GetData

{

get

{

return st;

}

}

}

Now build the dll. Then from the visual studio command prompt type type �regasm MyInterOp.dll /tlb:MyInterOp.tlb�.

Have look at the tlb using OleViewer

See the tagMyStruct. It have LPSTR.

Now create a console application in C++. It looks like this

HRESULT hr = CoInitialize(NULL);

ITest* pTest = NULL;

hr = CoCreateInstance(__uuidof(Test),NULL,CLSCTX_INPROC_SERVER,__uuidof(ITest),(void**)&pTest);

MyInterOp::MyStruct HUGEP *pBSTR;

hr = SafeArrayAccessData(pTest->GetData, (void HUGEP* FAR*)&pBSTR);

printf("Name: %S \n",pBSTR[0].name);

printf("SurName: %S \n",pBSTR[0].surname);

printf("Age: %d \n",pBSTR[0].age);

printf("Name: %S \n",pBSTR[1].name);

printf("SurName: %S \n",pBSTR[1].surname);

printf("Age: %d \n",pBSTR[1].age);

But when you run this application it will give you an exception.

If you debug, you can see that the HRESULT is �-2147319783� which means �Old format or invalid type library.�

So LPSTR is not going to work for us.

Solution

So now how we can solve the issue.

Make your struct look like this

[StructLayout(LayoutKind.Sequential)]

public struct MyStruct

{

[MarshalAs(UnmanagedType.BStr)]

public string name;

[MarshalAs(UnmanagedType.BStr)]

public string surname;

public int age;

}

Register the dll once again and look at the tlb.

See that now it is BSTR instead of LPSTR.

Now run the C++ Console application

Requirements

In order to run mz test application

1) Open the C# solution in a VS 2005.

2) Build the Solution.

3) Use regasm to register the tlb

4) Open the C++ dsw in VS 6.

5) In the #import section, Refer to appropriate location in your machine. �#import "E:\MyTestApps\TestInterOp\Debug\MyInterOp.tlb"�

6) Run the Console application and that�s it.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: