473,785 Members | 2,327 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Marshalling a SAFEARRAY from an ATL component into CS.

I've written an ATL 7.1 component and have a C# 1.1 client that is
consuming it. The ATL component has a method with a [out,retval] that
returns a SAFEARRAY of INTs, but my C# component chokes on it.
The C# code:

// Display a message box with a value from the ATL control
private void GoButton_Click( object sender, System.EventArg s e)
{
SAServerLib.bob Class foo = new SAServerLib.bob Class();

object o = foo.Populate();
MessageBox.Show ( o.ToString() );

int[] ch = (int[])o;
MessageBox.Show ( ch.ToString() );
}
I receive an exception on:
int[] ch = (int[])o;

With the message being:
"An unhandled exception of type 'System.Invalid CastException' occurred
in Safearrays.exe

Additional information: Specified cast is not valid."
ATL code:

// Populate a safe array with the value "321".
STDMETHODIMP Cbob::Populate( SAFEARRAY** saData)
{
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = 3;

*saData = SafeArrayCreate (VT_BSTR, 1, rgsabound);

long c = 3;
long lCount = 0L;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );

c = 2;
lCount++;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );

c = 1;
lCount++;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );

return S_OK;
}
All of this code is from a sample application I'm just trying to prove
the concept with. (Eventually I'll be returning SAFEARRAY's of custom
structures.)

I've googled and MSDNed for some information, but Any advice would be
greatly appreciated.

Cheers.
Nov 17 '05 #1
5 6927
have you check out this page on MSDN:

http://msdn.microsoft.com/library/de...gForArrays.asp

HTH

Ollie Riches

"Tronster Hartley" <tr************ **@thomson.com> wrote in message
news:uf******** *****@TK2MSFTNG P12.phx.gbl...
I've written an ATL 7.1 component and have a C# 1.1 client that is
consuming it. The ATL component has a method with a [out,retval] that
returns a SAFEARRAY of INTs, but my C# component chokes on it.
The C# code:

// Display a message box with a value from the ATL control
private void GoButton_Click( object sender, System.EventArg s e)
{
SAServerLib.bob Class foo = new SAServerLib.bob Class();

object o = foo.Populate();
MessageBox.Show ( o.ToString() );
int[] ch = (int[])o;
MessageBox.Show ( ch.ToString() );
}
I receive an exception on:
int[] ch = (int[])o;

With the message being:
"An unhandled exception of type 'System.Invalid CastException' occurred in
Safearrays.exe

Additional information: Specified cast is not valid."
ATL code:

// Populate a safe array with the value "321".
STDMETHODIMP Cbob::Populate( SAFEARRAY** saData)
{
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = 3;

*saData = SafeArrayCreate (VT_BSTR, 1, rgsabound);

long c = 3;
long lCount = 0L;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );
c = 2;
lCount++;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );
c = 1;
lCount++;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );
return S_OK;
}
All of this code is from a sample application I'm just trying to prove the
concept with. (Eventually I'll be returning SAFEARRAY's of custom
structures.)

I've googled and MSDNed for some information, but Any advice would be
greatly appreciated.

Cheers.

Nov 17 '05 #2
Please post your method declaration (midl).
I'm not clear how you declared your SAFEARRAY return argument, as far as I
know you can't return a safearray (retval)
Willy.

"Tronster Hartley" <tr************ **@thomson.com> wrote in message
news:uf******** *****@TK2MSFTNG P12.phx.gbl...
I've written an ATL 7.1 component and have a C# 1.1 client that is
consuming it. The ATL component has a method with a [out,retval] that
returns a SAFEARRAY of INTs, but my C# component chokes on it.
The C# code:

// Display a message box with a value from the ATL control
private void GoButton_Click( object sender, System.EventArg s e)
{
SAServerLib.bob Class foo = new SAServerLib.bob Class();

object o = foo.Populate();
MessageBox.Show ( o.ToString() );
int[] ch = (int[])o;
MessageBox.Show ( ch.ToString() );
}
I receive an exception on:
int[] ch = (int[])o;

With the message being:
"An unhandled exception of type 'System.Invalid CastException' occurred in
Safearrays.exe

Additional information: Specified cast is not valid."
ATL code:

// Populate a safe array with the value "321".
STDMETHODIMP Cbob::Populate( SAFEARRAY** saData)
{
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = 3;

*saData = SafeArrayCreate (VT_BSTR, 1, rgsabound);

long c = 3;
long lCount = 0L;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );
c = 2;
lCount++;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );
c = 1;
lCount++;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );
return S_OK;
}
All of this code is from a sample application I'm just trying to prove the
concept with. (Eventually I'll be returning SAFEARRAY's of custom
structures.)

I've googled and MSDNed for some information, but Any advice would be
greatly appreciated.

Cheers.

Nov 17 '05 #3
You may be right in terms of SAFEARRAYs not able to be returned; the
MSDN article pointed to by Ollie Riches seems to show that an in or
in/out parameter is the only type that can be decorated for marshaling.
:( (I hope that isn't true.)


Below is the IDL:

import "oaidl.idl" ;
import "ocidl.idl" ;

[
uuid(0A15D60D-B87D-4B1C-AA85-07BF51CB6FF0),
version(1.0),
helpstring("SAS erver 1.0 Type Library")
]
library SAServerLib
{
importlib("stdo le2.tlb");
[
uuid(908FF2FF-CA80-4858-BD8D-89CFF5CAFEA3),
helpstring("_Ib obEvents Interface")
]
dispinterface _IbobEvents
{
properties:
methods:
};

[
object,
uuid(1C4CD34D-8B6D-4571-B00A-4930FD1FFAF0),
dual,
nonextensible,
helpstring("Ibo b Interface"),
pointer_default (unique)
]
interface Ibob : IDispatch{
[id(1), helpstring("met hod Populate")]
HRESULT Populate([out,retval] SAFEARRAY** saData);
};

[
uuid(D9C4E6D0-4A9F-4A8F-95EC-6ACACBACB67C),
helpstring("bob Class")
]
coclass bob
{
[default] interface Ibob;
[default, source] dispinterface _IbobEvents;
};
};

Willy Denoyette [MVP] wrote:
Please post your method declaration (midl).
I'm not clear how you declared your SAFEARRAY return argument, as far as I
know you can't return a safearray (retval)
Willy.

"Tronster Hartley" <tr************ **@thomson.com> wrote in message
news:uf******** *****@TK2MSFTNG P12.phx.gbl...
I've written an ATL 7.1 component and have a C# 1.1 client that is
consuming it. The ATL component has a method with a [out,retval] that
returns a SAFEARRAY of INTs, but my C# component chokes on it.
The C# code:

// Display a message box with a value from the ATL control
private void GoButton_Click( object sender, System.EventArg s e)
{
SAServerLib.bob Class foo = new SAServerLib.bob Class();

object o = foo.Populate();
MessageBox.Show ( o.ToString() );
int[] ch = (int[])o;
MessageBox.Show ( ch.ToString() );
}
I receive an exception on:
int[] ch = (int[])o;

With the message being:
"An unhandled exception of type 'System.Invalid CastException' occurred in
Safearrays.exe

Additional information: Specified cast is not valid."
ATL code:

// Populate a safe array with the value "321".
STDMETHODIMP Cbob::Populate( SAFEARRAY** saData)
{
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = 3;

*saData = SafeArrayCreate (VT_BSTR, 1, rgsabound);

long c = 3;
long lCount = 0L;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );
c = 2;
lCount++;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );
c = 1;
lCount++;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );
return S_OK;
}
All of this code is from a sample application I'm just trying to prove the
concept with. (Eventually I'll be returning SAFEARRAY's of custom
structures.)

I've googled and MSDNed for some information, but Any advice would be
greatly appreciated.

Cheers.


Nov 17 '05 #4
Thank you Ollie.

I had not found that page in my searches. I'm gleaning information from
it now as I try to get this to work.

Cheers.
Ollie Riches wrote:
have you check out this page on MSDN:

http://msdn.microsoft.com/library/de...gForArrays.asp

HTH

Ollie Riches

"Tronster Hartley" <tr************ **@thomson.com> wrote in message
news:uf******** *****@TK2MSFTNG P12.phx.gbl...
I've written an ATL 7.1 component and have a C# 1.1 client that is
consuming it. The ATL component has a method with a [out,retval] that
returns a SAFEARRAY of INTs, but my C# component chokes on it.
The C# code:

// Display a message box with a value from the ATL control
private void GoButton_Click( object sender, System.EventArg s e)
{
SAServerLib.bob Class foo = new SAServerLib.bob Class();

object o = foo.Populate();
MessageBox.Show ( o.ToString() );
int[] ch = (int[])o;
MessageBox.Show ( ch.ToString() );
}
I receive an exception on:
int[] ch = (int[])o;

With the message being:
"An unhandled exception of type 'System.Invalid CastException' occurred in
Safearrays.exe

Additional information: Specified cast is not valid."
ATL code:

// Populate a safe array with the value "321".
STDMETHODIMP Cbob::Populate( SAFEARRAY** saData)
{
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = 3;

*saData = SafeArrayCreate (VT_BSTR, 1, rgsabound);

long c = 3;
long lCount = 0L;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );
c = 2;
lCount++;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );
c = 1;
lCount++;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );
return S_OK;
}
All of this code is from a sample application I'm just trying to prove the
concept with. (Eventually I'll be returning SAFEARRAY's of custom
structures.)

I've googled and MSDNed for some information, but Any advice would be
greatly appreciated.

Cheers.


Nov 17 '05 #5
You should indicate the type of SAFEARRAY element, so your IDL should look
like this:

[id(1), helpstring("met hod Populate")] HRESULT Populate([out,
retval]SAFEARRAY(int)* psa);

STDMETHODIMP CBob::Populate( SAFEARRAY** psa)
{

As such in C#, you can return into an int[]

int[] ia = obj.Populate();

Willy.

Tronster Hartley" <tr************ **@thomson.com> wrote in message
news:%2******** ********@TK2MSF TNGP14.phx.gbl. ..
You may be right in terms of SAFEARRAYs not able to be returned; the MSDN
article pointed to by Ollie Riches seems to show that an in or in/out
parameter is the only type that can be decorated for marshaling. :( (I
hope that isn't true.)

Below is the IDL:

import "oaidl.idl" ;
import "ocidl.idl" ;

[
uuid(0A15D60D-B87D-4B1C-AA85-07BF51CB6FF0),
version(1.0),
helpstring("SAS erver 1.0 Type Library")
]
library SAServerLib
{
importlib("stdo le2.tlb");
[
uuid(908FF2FF-CA80-4858-BD8D-89CFF5CAFEA3),
helpstring("_Ib obEvents Interface")
]
dispinterface _IbobEvents
{
properties:
methods:
};

[
object,
uuid(1C4CD34D-8B6D-4571-B00A-4930FD1FFAF0),
dual,
nonextensible,
helpstring("Ibo b Interface"),
pointer_default (unique)
]
interface Ibob : IDispatch{
[id(1), helpstring("met hod Populate")]
HRESULT Populate([out,retval] SAFEARRAY** saData);
};

[
uuid(D9C4E6D0-4A9F-4A8F-95EC-6ACACBACB67C),
helpstring("bob Class")
]
coclass bob
{
[default] interface Ibob;
[default, source] dispinterface _IbobEvents;
};
};

Willy Denoyette [MVP] wrote:
Please post your method declaration (midl).
I'm not clear how you declared your SAFEARRAY return argument, as far as
I know you can't return a safearray (retval)
Willy.

"Tronster Hartley" <tr************ **@thomson.com> wrote in message
news:uf******** *****@TK2MSFTNG P12.phx.gbl...
I've written an ATL 7.1 component and have a C# 1.1 client that is
consuming it. The ATL component has a method with a [out,retval] that
returns a SAFEARRAY of INTs, but my C# component chokes on it.
The C# code:

// Display a message box with a value from the ATL control
private void GoButton_Click( object sender, System.EventArg s e)
{
SAServerLib.bob Class foo = new SAServerLib.bob Class();

object o = foo.Populate();
MessageBox.Show ( o.ToString() );
int[] ch = (int[])o;
MessageBox.Show ( ch.ToString() );
}
I receive an exception on:
int[] ch = (int[])o;

With the message being:
"An unhandled exception of type 'System.Invalid CastException' occurred
in Safearrays.exe

Additional information: Specified cast is not valid."
ATL code:

// Populate a safe array with the value "321".
STDMETHODIMP Cbob::Populate( SAFEARRAY** saData)
{
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = 3;

*saData = SafeArrayCreate (VT_BSTR, 1, rgsabound);

long c = 3;
long lCount = 0L;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );
c = 2;
lCount++;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );
c = 1;
lCount++;
SafeArrayPutEle ment(*saData, &lCount, static_cast<voi d*>(&c) );
return S_OK;
}
All of this code is from a sample application I'm just trying to prove
the concept with. (Eventually I'll be returning SAFEARRAY's of custom
structures.)

I've googled and MSDNed for some information, but Any advice would be
greatly appreciated.

Cheers.


Nov 17 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
1297
by: Patrice FRITSCH | last post by:
Does anybody know how to retrieve a safearray from a Component ? In my asp code, I create an instance of the object, and I try to retrieve an array of 3 strings. Set myObject = CreateObject("A.B") Dim arrSoft(3) iRet = myObject.GetSoftVersions(arrSoft...)
0
1960
by: Bob | last post by:
I have been trying to us an unmanaged dll for a while now with no good results. Most of the dll methods i can use and have been. I however have a problem with this one. I am supposed to ref 15 objects as the following type. This is one of the 15 variables i am using. object secondaryFieldScoreDataSA = new int ;
4
10324
by: Roland Moschel | last post by:
Hi there ! I have some Problems to get a SafeArray out of a COM Server written in (Unmanaged) C++. From (unmanaged) Visual Basic , everything is ok , but unfortunately in C# I get an exception. Can anybody help me ?
0
1912
by: Andrew S. Giles | last post by:
Helo all, I have a standalone unmanaged C++ application that makes a call on another standalone COM server, which raises an event that should be handled in C#. I am trying to send: unsigned long, double, BSTR, and VARIANT. The unsigned long, double, and BSTR (marshalled to System.String) work just fine and dandy.
5
3111
by: Ahmad Jalil Qarshi | last post by:
i want to store binary data into my property. i read earlier positing on "microsoft.public.dotnet.languages.vc" group with subject as SAFEARRAY in attributed ATL7 Project. i followed the same approach but unfortunately i failed to do that. i declared the property accessors as follow in my idl file. HRESULT Data( SAFEARRAY * *pVal); HRESULT Data( SAFEARRAY * newVal); when i compile code i get following error.
10
2551
by: Bryce Calhoun | last post by:
Hello, First of all, this is a .NET 1.1 component I'm creating. SUMMARY ----------------------- This component that I'm creating is, for all intents and purposes, a document parser (I'm actually deserializing a SOAP document into an object and parsing out the fields, but that's fairly immaterial to this
1
6016
by: Brendan Grant | last post by:
I’ve got a C# library that I’ve built into a COM component that will be used from a VC++ 6 application and while the creation of the COM object side of things seem to be working fine, using the object fully is another matter. On the C# side of things I’ve got an object defined like so: public class PID : IPID { private string type;
5
6350
by: Maxim | last post by:
Hi all, I'm calling a COM Interface method that returnes SafeArray wrapped into variant. Is it possible to convert it to managed array? Because working with SAFEARRAY directly is a bit complicated. Or maybe there is a managed wrapper class for safe array? Thanks in advance.
0
3225
skeptics
by: skeptics | last post by:
Trying to pass a SafeArray that i get form Request.BinaryRead Method in classic asp to a c# com interop component. In this thread i found a solution to pass and cast a normal asp safearray in to a c# array: http://bytes.com/groups/net/114755-passing-safearray-bytes-vbscript-managed-com-object-c#goto_threadtools but no matter what i try. i cant pass a array that i get from Request.BinaryRead Method in to the component. i always get a error...
0
9491
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10357
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10163
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10104
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9959
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8988
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7510
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5532
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4063
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.