1

I am looking for a way to pass a byte array from a c# COM object to IIS/ASP (not .NET). I was going to pass it using strings, but while ASP handles binary data in strings without problems, C# does not. This means I cannot expect a byte array converted to string and passed to ASP to be identical to the original array. Also, when having the array in ASP, I need to send it unchanged as a response (Response.Write).

I found this SO answer - How to correctly marshal VB-Script arrays to and from a COM component written in C# explaining how to pass arrays, but it isn't clear to me how I am supposed to pass a byte array and how to assemble the array to a string in ASP.

Any pointers? I already have the COM object and can pass data (strings, int, etc) back and forth. The byte array part eludes me.

Edit: This is what I use now (and what does not work at all):

    [DispId(1003)]
    byte[] arrayOut { set; get; }
Community
  • 1
  • 1
galmok
  • 869
  • 10
  • 21
  • Currently I am thinking about storing the data on disk in the C# COM object and pass a filename to ASP for it to read, but it seems a more direct way should be possible. – galmok Mar 04 '14 at 15:33
  • 1
    Here's some info that might be helpful: http://www.motobit.com/tips/detpg_binarytostring/ I have used CreateObject("ADODB.Recordset") and AppendChunk in the past with some success. – Nathan Rice Mar 04 '14 at 22:59

2 Answers2

1

It turns out my original conclusion about the shown code not to be working at all was wrong. It seems .NET makes the necessary wrapping and the problem was located in my ASP section. I was using Response.Write which showed garbled (chinese) output but when I switched to use Response.BinaryWrite, it worked perfectly. So, manually marshalling the array turned out not to be nessary.

Basic C# project is setup like this.

First an interface:

[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)]
interface FillArrayI
{
    // Properties
    [DispId(1000)]
    byte[] result_array { set; get; }

    [DispId(2000)]
    int fill_result_array();
}

Next a class:

[ProgId("ArrayTest.FillAray")]
[GuidAttribute("51E7819D-3EF3-4498-B5BE-5D6B8EF98176")] // some guid
[ClassInterface(ClassInterfaceType.AutoDispatch)]
public class FillArray : FillArrayI
{
    public byte[] result_array{ set; get; }
    public int fill_result_array()
    {
        result_array = new byte[95];
        for(int i = 0; i < 95; result_array[i] = i+32;
        return 0;
    }
}

Compile and load the COM object (one or both of these, correct for .NET version used):

"%WINDIR%\Microsoft.NET\Framework\v4.0.30319\regasm.exe" ArrayTest.dll /tlb /codebase /register
"%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\regasm.exe" ArrayTest.dll /tlb /codebase /register

Load with this ASP file:

Dim comObj
Set comObj = Server.CreateObject("ArrayTest.FillArray")
returnCode = comObj.fill_result_array
Response.WriteBinary comObj.result_array

I believe this is should do the trick.

galmok
  • 869
  • 10
  • 21
  • Could you add sample code for both parts (C# and ASP), to help others that reach this question? – ferhrosa Nov 24 '14 at 11:24
  • I don't have the code anymore, but I'll try to add what I believe is what is needed to get the byte array out from a C# COM object. – galmok Nov 25 '14 at 12:27
0

Going off the article you mention in your question have you tried?

[DispId(1003)]
byte[] arrayOut {
  [return: MarshalAs(UnmanagedType.Struct, SafeArraySubType = VarEnum.VT_ARRAY)]
  get;
}

Your issue is that Classic ASP uses VBScript which expects a SAFEARRAY of variants so you need to marshal your property to return that.

user692942
  • 16,398
  • 7
  • 76
  • 175
  • 1
    Actually, what turned out to be enough, was to use `Response.BinaryWrite` in the ASP file. What I declared in C# is what I ended up with. I just didn't know the BinaryWrite command and just used Write which output garbled data. Should this end up as an answer? – galmok Mar 07 '14 at 15:00
  • @galmok Yeah you should add it as an answer to help others who come across this question. See [Can I answer my own question?](http://stackoverflow.com/help/self-answer). – user692942 Mar 07 '14 at 15:05