Thread: Inject .NET assembly in native process

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    77

    Inject .NET assembly in native process

    Hi,
    I'm using a very simple Inter Process Communication using the ICLRRuntimeHost interface and it's method ExecuteInDefaultAppDomain.
    This approach allows to make communications between a C application and a .net dll in a couple of lines.

    However, as I am allowed to send a string from C as argument of the method to execute in .net (C#), I'm constraint by the ExecuteInDefaultAppDomain to receive only a DWORD-type variable (integer).
    I would like to know if there is a mean (another method of the interface to use) so that I can receive in return of the call a string.
    Many thanks!

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You can create a C++/CLI go-between ref class and communicate via .NET data types. The C/C++ can talk to the C++/CLI and the C++/CLI can talk to the C#.

    But I have very little experience with inter-process communication between native and managed code.

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    77
    Thanks Bubba!
    I've got the solution from Microsoft. There is no other method for this mechanism. Therefore, using ExecuteInDefaultAppDomain is the only one allowed to do that and it sends a string and returns an integer.

  4. #4
    Registered User
    Join Date
    Jan 2010
    Posts
    412
    Yes it is true that the only return type allowed is an int, but you can use that to return a pointer to a string

    Managed code:
    Code:
    using System.Runtime.InteropServices;
    
    public class TestClass
    {
            [DllImport("kernel32")]
            static extern IntPtr GetProcessHeap();
            [DllImport("kernel32")]
            static extern IntPtr HeapAlloc(IntPtr hHeap, HeapAllocFlags flags, int size);
    
            [Flags]
            public enum HeapAllocFlags
            {
                HEAP_NO_SERIALIZE = 0x00000001,
                HEAP_GENERATE_EXCEPTIONS = 0x00000004,
                HEAP_ZERO_MEMORY = 0x00000008,
            }
    
            public static int TestFunc(string args)
            {
                try
                {
                    IntPtr Heap, StringMemory;
                    string ret = "Passed argument string was: " + args;
    
                    // Get a handle to the default heap
                    if ((Heap = GetProcessHeap()) == IntPtr.Zero)
                        throw new InvalidOperationException("GetProcessHeap() failed");
                    
                    // Unicode string 2 bytes per character, plus terminating NULL char
                    int MemSize = ret.Length * 2 + 1;
                    
                    // Allocate new memory on the heap
                    if((StringMemory = HeapAlloc(Heap, HeapAllocFlags.HEAP_ZERO_MEMORY, MemSize)) == IntPtr.Zero)
                        throw new OutOfMemoryException("HeapAlloc() failed to allocate " + MemSize + " bytes.");
    
                    // Copy the string to unmanaged memory
                    Marshal.Copy(ret.ToCharArray(), 0, StringMemory, ret.Length);
    
                    // Return a pointer to our memory block
                    return (int)StringMemory;
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                }
                return 0;
            }
        }
    Unmanaged code:
    Code:
    DWORD dwRet = 0;
    if(FAILED(CallManagedFunc(L"Managed.TestClass", L"TestFunc", L"1234567890", &dwRet)))
    	OutputDebugString(L"CallManagedFunc() failed.\n");
    
    if(dwRet)
    {
    	MessageBoxW(NULL, (TCHAR*)dwRet, L"!", MB_OK);
    	// Free our memory to avoid memory leaks
    	HeapFree(GetProcessHeap(), 0, (LPVOID)dwRet);
    }
    See
    GetProcessHeap Function (Windows)
    HeapAlloc Function (Windows)
    HeapFree Function (Windows)
    for reference

    Edit:
    Forgot to include the CallManagedFunc function. Although it's just a wrapper for ExecuteInDefaultAppDomain I'm adding it for completeness
    Code:
    HRESULT CallManagedFunc(LPCWSTR className, LPCWSTR funcName, LPCWSTR args, DWORD* dwRet)
    {
    	return g_ClrHost->ExecuteInDefaultAppDomain(
    		g_PathToDLL,
    		className,
    		funcName,
    		args,
    		dwRet);
    }
    Last edited by _Mike; 01-25-2010 at 12:29 AM. Reason: Adding CallManagedFunc()

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. assembly language...the best tool for game programming?
    By silk.odyssey in forum Game Programming
    Replies: 50
    Last Post: 06-22-2004, 01:11 PM
  2. IE 6 status bar
    By DavidP in forum Tech Board
    Replies: 15
    Last Post: 10-23-2002, 05:31 PM
  3. Your opinion about .NET
    By Shiro in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 04-05-2002, 02:55 PM
  4. .net
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 02-15-2002, 01:15 AM
  5. Visual J#
    By mfc2themax in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 10-08-2001, 02:41 PM