VC的DLL配合C#達到動態配置記憶體 & DLL使用RUNDLL32標準測試語法

VC的DLL配合C#達到動態配置記憶體 & DLL使用RUNDLL32標準測試語法

VCDLL配合C#達到動態配置記憶體 & DLL使用RUNDLL32標準測試語法


 


GITHUB: https://github.com/jash-git/jashliao_VC/tree/master/002_DLL%E5%AE%8C%E6%95%B4%E8%A8%AD%E8%A8%88%E7%AF%84%E4%BE%8B/15_VC%E7%9A%84DLL_C%23%E5%8B%95%E6%85%8B%E9%85%8D%E7%BD%AE%E8%A8%98%E6%86%B6%E9%AB%94%E5%92%8CDLL%E4%BD%BF%E7%94%A8RUNDLL32%E6%A8%99%E6%BA%96%E6%B8%AC%E8%A9%A6%E8%AA%9E%E6%B3%95


[jashliao_VC/002_DLL完整設計範例/15_VC的DLL_C#動態配置記憶體和DLL使用RUNDLL32標準測試語法/]




VCDLL

H檔案

#ifndef c_MathFuncsDll_H

#define c_MathFuncsDll_H

 

#include <stdio.h>

 

typedef struct _Data

{

 bool bData;

 int nData;

 char strData[256];

} Data;

 

struct Bar

{

  public :

     int id;

     char*
name;

};

extern “C”{

  __declspec(dllexport) int Test_AllocData(int count, Data*& res);

  __declspec(dllexport) int Test_FreeData(Data* d);

  __declspec(dllexport) int GetBar(Bar& bar);

  __declspec(dllexport) int SaveByteArray(BYTE * pArray, int nSize);

    // Returns a +
b

  __declspec(dllexport) double Add(double a, double b);

 

  // Returns a – b

  __declspec(dllexport) double Subtract(double a, double b);

 

  // Returns a * b

  __declspec(dllexport) double Multiply(double a, double b);

 

  // Returns a / b

  __declspec(dllexport) double Divide(double a, double b);

  __declspec(dllexport) void EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);

    }

#endif

 

CPP

// c_MathFuncsDll.cpp : wMq DLL 3DIg!o¡ÑDXLc!C

//

 

#include “stdafx.h”

#include <stdio.h>

#include “c_MathFuncsDll.h”

 

int Test_AllocData(int count, Data*& res)

{

  res = new Data[count];

  for(int i=0 ; i<count ; i++)

  {

     /*

     http://falldog7.blogspot.tw/2015/01/c-sharp-allocate-structure-buffer-array-dll.html

     */

     res[i].bData = true;

     res[i].nData = 500 + i;

     sprintf_s(res[i].strData, “Test_AllocData(%d)”, i);

  }

  return 0;

}

int Test_FreeData(Data* d)

{

  /*

  http://falldog7.blogspot.tw/2015/01/c-sharp-allocate-structure-buffer-array-dll.html

  */

  if(d)

  {

     delete []
d;

  }

  return 0;

}

int GetBar(Bar& bar)

{

  /*

  http://www.cnblogs.com/yukaizhao/archive/2011/04/27/csharp_call_cpp_class_struct.html

  */

  FILE *pf;

  pf=fopen(“data.txt”,“a”);

  fprintf(pf,“bar.id=%d\tbar.name=%s\n”,bar.id,bar.name);

  fprintf(pf,“\n”);

  fclose(pf);

  bar.id = 10;

    bar.name = “hi
bar
?aF”;

  return 0;

}

int SaveByteArray(BYTE * pArray, int nSize)

{

  /*

  https://social.msdn.microsoft.com/Forums/en-US/32f1a857-91d6-472d-b333-469ed7f6f6dd/passing-a-byte-array-to-a-c-dll-from-c?forum=csharplanguage

  */

  FILE *pf;

  pf=fopen(“data.txt”,“a”);

  for (int i=0; i<nSize; i++)

  {

        fprintf(pf,“%d,”,
pArray[i]);

  }

  fprintf(pf,“\n”);

  fclose(pf);

  return 0;

}

double Add(double a, double b)

{

    return a
+ b;

}

 

double Subtract(double a, double b)

{

    return a
– b;

}

 

double Multiply(double a, double b)

{

    return a
* b;

}

 

double Divide(double a, double b)

{

    if (b ==
0)

    {

        return -1;

    }

 

    return a
/ b;

}

void EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR
lpszCmdLine, int nCmdShow)//for RUNDLL32.EXE <dllname>,<entrypoint>
<optional arguments>

{

  //https://support.microsoft.com/zh-tw/kb/164787

  /*

  ia!u

 

     RUNDLL.EXE
SETUPX.DLL,InstallHinfSection 132 C:\WINDOWS\INF\SHELL.INF

  hwnd = (parent window handle)

  hinst = HINSTANCE of SETUPX.DLL

  lpszCmdLine = “132
C:\WINDOWS\INF\SHELL.INF”

  nCmdShow = (whatever the nCmdShow
was passed to CreateProcess)

  */

  //¦uMO:RUNDLL32.EXE
c_MathFuncsDll.dll,EntryPoint jash.liao

  FILE *pf;

  pf=fopen(“123.txt”,“w”);

  fprintf(pf,“%s”,lpszCmdLine);

  fclose(pf);

}

 

 

_

 


C#

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

using System.Runtime.InteropServices;//USE DLL

 

namespace ConsoleApplication1

{

    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]

    public struct Bar

    {

 

        /// int

        public int id;

 

        /// char*

        [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]

        public string name;

    }

 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

    public struct Data

    {

        public bool bData;

        public int nData;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]

        public string strData;

    }

 

    class Program

    {

        //*

        [DllImport(“./c_MathFuncsDll.dll”,
CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Ansi, EntryPoint = “Test_AllocData”)]

        public static extern void Test_AllocData(int size, ref IntPtr ptr);

        [DllImport(“./c_MathFuncsDll.dll”,
CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Ansi, EntryPoint = “Test_FreeData”)]

        public static extern void Test_FreeData(IntPtr ptr);

        [DllImport(“./c_MathFuncsDll.dll”,
CallingConvention = CallingConvention.Cdecl,CharSet=CharSet.Ansi, EntryPoint = “GetBar”)]

        extern static void GetBar(ref Bar bar);

        [DllImport(“./c_MathFuncsDll.dll”,
CallingConvention = CallingConvention.Cdecl,
EntryPoint = “SaveByteArray”)]

        static extern Int32 SaveByteArray(IntPtr pArray, int nSize);

        [DllImport(“./c_MathFuncsDll.dll”,
CallingConvention = CallingConvention.Cdecl,
EntryPoint = “Add”)]

        static extern double Add(double a, double b);

        [DllImport(“./c_MathFuncsDll.dll”,
CallingConvention = CallingConvention.Cdecl,
EntryPoint = “Subtract”)]

        static extern double Subtract(double a, double b);

        [DllImport(“./c_MathFuncsDll.dll”,
CallingConvention = CallingConvention.Cdecl,
EntryPoint = “Multiply”)]

        static extern double Multiply(double a, double b);

        [DllImport(“./c_MathFuncsDll.dll”,
CallingConvention = CallingConvention.Cdecl,
EntryPoint = “Divide”)]

        static extern double Divide(double a, double b);

        //*/

    /*

   
[DllImport(“msvcrt.dll”)]

    public static extern int
puts(string c);

 

   
[DllImport(“msvcrt.dll”)]

    public static extern int
_flushall();

     */

        static void Pause()

        {

            Console.Write(“Press any key to continue . . . “);

            Console.ReadKey(true);

        }

        static void Main(string[]
args)

        {

            ///*

            double d1 = 5.0d;

            double d2 = 20.0d;

            double d3=0.0;

            d3 = Add(d1, d2);

            Console.WriteLine(“HELLO WORD”);

            Console.WriteLine(“d1=” + d1);

            Console.WriteLine(“d2=” + d2);

            Console.WriteLine(“d3=” + d3);

 

            //============================

            byte[]
array = new byte[16];

 

            for (int i = 0; i < 16; i++)

            {

                array[i] = (byte)(i + 97);

            }

           

            int size = Marshal.SizeOf(array[0]) *
array.Length;

            IntPtr pnt = Marshal.AllocHGlobal(size);

            try

            {

                //
Copy the array to unmanaged memory.

                Marshal.Copy(array,
0, pnt, array.Length);

            }

            finally

            {

                //
Free the unmanaged memory.

                //
Marshal.FreeHGlobal(pnt);

                Console.WriteLine(“C# data 2 C++ error”);

            }

            SaveByteArray(pnt, array.Length);

            Marshal.FreeHGlobal(pnt);

            //============================

            Bar b = new Bar();

            b.id = 100;

            b.name = “hi
bar English”
;

            GetBar(ref b);

            Console.WriteLine(“b’s id is “ + b.id);

            Console.WriteLine(“b’s name is “ + b.name);

 

            //
testing for retrive struct array buffer from DLL

            IntPtr binary = new IntPtr();

            {

                Data[]
ad = new Data[3];

                Test_AllocData(3, ref binary);

                ad[0] = (Data)Marshal.PtrToStructure(binary
+ Marshal.SizeOf(typeof(Data)) * 0, typeof(Data));

                ad[1] = (Data)Marshal.PtrToStructure(binary
+ Marshal.SizeOf(typeof(Data)) * 1, typeof(Data));

                ad[2] = (Data)Marshal.PtrToStructure(binary
+ Marshal.SizeOf(typeof(Data)) * 2, typeof(Data));

                Test_FreeData(binary);

 

                for (int i = 0; i < 3; i++)

                {

                    Console.WriteLine(string.Format(“@AllocData
from DLL i={0} n={1} str={2}”
, i, ad[i].nData, ad[i].strData));

                }

            }

 

            Console.WriteLine(“Call C++ DLL finish”);

            //*/

            /*

           
puts(“Test”);

            _flushall();

            */

            Pause();

        }

    }

}

 

 

 

RUNDLL32標準測試

RUNDLL32.EXE
c_MathFuncsDll.dll,EntryPoint jash.liao

 

One thought on “VC的DLL配合C#達到動態配置記憶體 & DLL使用RUNDLL32標準測試語法

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *