c++ - How to call an ActiveX function with char * parameter in C# -


i have c++ function :

unsigned int readusermemory( unsigned char *lpbuffer, unsigned int iaddress, unsigned int nnumberofbyte ); 

which reads nnumberofbyte bytes iaddress of memory , places in lpbuffer.
created atl object it( going used in c# ) interface :

[id(6), helpstring("method readusermemory")] hresult readusermemory(byte* lpbuffer, [in] ulong iaddress, [in] ulong nnumberofbyte, [out,retval] ulong* result);   

i'm neither c# programmer nor experienced atl programmer! i'm going test function in c# code :

byte [] b = new byte[100]; axobj.readusermemory(b, 0, 100); 

but apparently code wrong. how call method? in advance.

i think peter r has valid point, in using com complicated, because requires learning com c++ , c#, you've discovered. c++ interop option, requires learning third technology, called c++/cli, probably better fit com, can still problematic. both com , c++/cli quite big, complicated beasts, might better off declaring c function need in dll , using p/invoke, see e.g. http://msdn.microsoft.com/en-us/magazine/cc164123.aspx. if so, magic want can found in how can pass pointer array using p/invoke in c#?.

assuming want continue down com route, had play around it, , me looks need going work via type library embedded in com dll. in short, couldn't make com interop work unsigned char *lpbuffer, although perhaps else can! type-library friendly type use safearray, way vb likes see arrays.

in case, idl becomes

[id(1)] hresult readusermemory([out] safearray(byte)* buffer, [in] ulong iaddress, [in] ulong nnumberofbyte, [out,retval] ulong* result); 

your c++ implementation looks this

stdmethodimp cobj::readusermemory(safearray ** pbuffer, ulong iaddress, ulong nnumberofbyte, ulong* result) {     if (pbuffer== nullptr)         return e_pointer;      safearray*& psa = *pbuffer;     safearraybound rgsabound[1];     rgsabound[0].llbound = 0;     rgsabound[0].celements = nnumberofbyte;     psa = safearraycreate(vt_ui1, 1, rgsabound);     if(psa == null)         return e_outofmemory;      void* data = nullptr;     safearrayaccessdata(psa, &data);     for(int i=0; i<nnumberofbyte; ++i) {         ((char*)data)[i] = (char)i;     }     safearrayunaccessdata(psa);      return s_ok; } 

the safearrayunaccessdata should called if code after safearrayaccessdata fails.

the c# client looks this, notably have changed byte[] system.array

    static void main(string[] args)     {         rumlib.iobj axobj = new rumlib.obj();         array = null;         axobj.readusermemory(out a, 2, 6);         (int = 0; < a.length; ++i)         {             console.write("{0},", a.getvalue(i));         }         console.writeline();     } 

and output of program is

0,1,2,3,4,5,

note there v marshalling, i.e. copying of data, data comes safearray c# array. might prohibitively costly you, in case suggest go c++/cli or p/invoke.


Comments

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -