2021年3月20日 星期六

C# 使用C++ DLL檔(回傳值)

延續上篇(C# 使用C++ DLL檔)之後,一般使用DLL時,除了將參數提供給DLL演算法做使用,也需將演算法結果從DLL回傳回去,所以這次就來說明如何回傳結果給C#吧。

目前我了解到如果要從DLL回傳結果給C#,都會使用指標做回傳,而我先前測試經驗,C++撰寫上比較不會遇到問題,但在接收端C#有遇過接不到數值、接錯值、或是跑久還造成程式當掉,重點是DLL除錯還不怎麼容易,像是瞎子摸象的感覺,如果有人知道怎樣較快除DLL的Bug,再歡迎留言告訴我,感謝!!!經過一番的測試之後,我目前可正常回傳的資訊分別為字串與float陣列資訊。

Extern.cpp

#ifdef SYSALGORITHM_EXPORTS
#define SYSALGORITHM_API __declspec(dllexport)
#include "SysAlgorithm.h"

extern "C" SYSALGORITHM_API int add(int a, int b)
{
	Calculator Calculator;
	return Calculator.add(a, b);
}

extern "C" SYSALGORITHM_API int subtract(int a, int b)
{
	Calculator Calculator;
	return Calculator.subtract(a, b);
}

extern "C" SYSALGORITHM_API void getDLLValue(float * DLLvalue)
{
	Calculator Calculator;
	return Calculator.getDLLValue(DLLvalue);
}

extern "C" SYSALGORITHM_API void getDLLInfo(char * DLLInfo)
{
	Calculator Calculator;
	return Calculator.getDLLInfo(DLLInfo);
}

#endif

SysAlgorithm.h

#pragma once
#ifndef SYSALGORITHM_H
#define SYSALGORITHM_H

#include <fstream>
#include <string>

class Calculator
{
public:
	Calculator();
	~Calculator();

	int add(int a, int b);
	int subtract(int a, int b);
	void getDLLValue(float * DLLvalue);
	void getDLLInfo(char * DLLInfo);
};

#endif // !SYSALGORITHM_H 

SysAlgorithm.cpp

#include "SysAlgorithm.h"

Calculator::Calculator()
{

}

Calculator::~Calculator()
{

}

int Calculator::add(int a, int b)
{
	return(a + b);
}

int Calculator::subtract(int a, int b)
{
	return(a - b);
}

void Calculator::getDLLValue(float * DLLvalue)
{
	DLLvalue[0] = 0;
	DLLvalue[1] = 1.2;
	DLLvalue[2] = -1.2;
}

void Calculator::getDLLInfo(char * DLLInfo)
{
	char Info[20] = "return DLLInfo";
	strcpy_s(DLLInfo, strlen(Info) + 1, Info);
} 

C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace SysUI
{
    public partial class Form1 : Form
    {
        [DllImport("SysAlgorithm.dll", EntryPoint = "add", CallingConvention = CallingConvention.Cdecl)]
        private static extern int add(int a, int b);

        [DllImport("SysAlgorithm.dll", EntryPoint = "subtract", CallingConvention = CallingConvention.Cdecl)]
        private static extern int subtract(int a, int b);

        [DllImport("SysAlgorithm.dll", EntryPoint = "getDLLValue", CallingConvention = CallingConvention.Cdecl)]
        private static extern void getDLLValue([MarshalAs(UnmanagedType.LPArray)]float[] value);

        [DllImport("SysAlgorithm.dll", EntryPoint = "getDLLInfo", CallingConvention = CallingConvention.Cdecl)]
        private static extern void getDLLInfo(StringBuilder DLLInfo);

        private StringBuilder DLLInfo = new StringBuilder(20);
        private float[] DLLvalue = new float[3];

        public Form1()
        {
            InitializeComponent();
            label1.Text = add(3, 5).ToString();
            label2.Text = subtract(3, 5).ToString();
            getDLLValue(DLLvalue);
            getDLLInfo(DLLInfo);
            label6.Text = DLLvalue[0].ToString() + "," + DLLvalue[1].ToString("F2") + "," + DLLvalue[2].ToString("F2");
            label8.Text = DLLInfo.ToString();
        }
    }
}
 
為了可以正確取得從DLL演算法回傳參數,C#的DllImport這邊很重要!!記得要注意


結果圖:


沒有留言:

張貼留言