C#调用C++封装(续)

53 篇文章 1 订阅
这边继续是关于那个读取txt文件的频率增加的问题,这边的C++封装继续改善后发觉系统稳定了,感谢john的不懈努力和完善精神,发觉自己已经被生活磨去了很多专研精神,这边先上C语言的封装代码:
</pre><pre name="code" class="cpp">
// OptionsPlay.SharedFile.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include <stdio.h>
#include <sys\timeb.h> 
#include <stdlib.h>
#include<windows.h>
//#define LINENUM 174
#define LINESIZE 428
#define TESTTIME 100
#define _CRT_SECURE_NO_DEPRECATE

extern "C"_declspec(dllexport) int ReadSharedFolder(char *p, const char*targetFile, int lineNum);

void resetLoc(int *loc)
{
	*loc = 0;
}

int ReadSharedFolder(char *p, const char*targetFile, int lineNum){
	FILE *fp = fopen(targetFile, "r");
	if (fp == NULL)
	{
		perror("Error opeing file");
		return -1;
	}

	// manual initial one-dimension array p
	for (int i = 0; i < lineNum * (LINESIZE - 1); i++){
		p[i] = '\0';
	}

	// initialize two-dimension array quotation
	char **quotation;
	quotation = new char*[lineNum];
	for (int j = 0; j < lineNum; j++){
		quotation[j] = new char[LINESIZE];
	}
	int loc = 0;

	while (fgets(quotation[loc], LINESIZE, fp) != NULL)
	{
		loc++;
	}
	for (int i = 1; i < loc - 1; i++){
		for (int j = 0; j < (LINESIZE - 1); j++){
			p[(i - 1) * (LINESIZE - 1) + j] = quotation[i][j];
		}
	}
	fclose(fp);
	//resetLoc(&loc);
	// free array quotation
	for (int i = 0; i < lineNum; i++){
		delete[] quotation[i];
		quotation[i] = NULL;
	}
	delete[] quotation;

	return 0;
}



首先这个代码用来填充/0很关键,否则会有缓冲区的不释放的乱码存在,比如/r/n之类的:

for (int i = 0; i < lineNum * (LINESIZE - 1); i++){
		p[i] = '\0';
	}

其次,quotation的delete也是让内存泄露不再发生,同时也避免了野指针:

for (int i = 0; i < lineNum; i++){
		delete[] quotation[i];
		quotation[i] = NULL;
	}
	delete[] quotation;

同时调用这段也做了一些调整, 主要是Marshal.FreeHGlobal来析构这个堆栈以及使用throw来抛出万一这个c的封装有异常抛出,这样不会让服务异常当机。

[DllImport("OptionsPlay.SharedFile.dll", EntryPoint = "ReadSharedFolder", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        public static extern int ReadSharedFolder(IntPtr p, [MarshalAs(UnmanagedType.LPStr)] string targetFile, int lineNum);
        public static byte[] GetData(string folder, string fileName, int lineNum, int filetypeFlag)
        {
            IntPtr p = System.IntPtr.Zero;
            try
            {
                if (filetypeFlag == 1)
                {
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    p = Marshal.AllocHGlobal(sizeof(char) * lineNum * lineSize);
                    if (ReadSharedFolder(p, fileName, lineNum) == -1)
                    {
                        Logger.Debug(string.Format("Error opening file ", fileName, stopwatch.ElapsedMilliseconds));
                        throw new System.IO.IOException("error opening txt file");
                    }
                    byte[] b = new byte[lineNum * lineSize];
                    Marshal.Copy(p, b, 0, lineNum * lineSize);
                    stopwatch.Stop();
                    Logger.Debug(string.Format("File {0} Copied in {1}ms", fileName, stopwatch.ElapsedMilliseconds));
                    return b;
                }
                else
                {
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();


                    string path = Path.Combine(folder, fileName);
                    byte[] result = File.ReadAllBytes(path);
                    stopwatch.Stop();


                    Logger.Debug(string.Format("File {0} Copied in {1}ms", fileName, stopwatch.ElapsedMilliseconds));
                    return result;
                }
            }
            catch (Exception ex)
            {
                Logger.Error("FromLocalDrive GetData Error", ex);
                throw;
            }
            finally
            {
                Marshal.FreeHGlobal(p);
            }
        }
   


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#调用 C++ 的类可以使用 C++/CLI(Managed C++)来实现。C++/CLI 是一种混合语言,可以同时使用 C++C#。通过创建一个 C++/CLI 类,将 C++ 类包装为公共成员,并在 C# 中直接调用该类的方法。 以下是一个示例: ```cpp // C++ Class class MyCppClass { private: int value; public: MyCppClass(int v) : value(v) {} int GetValue() { return value; } }; ``` ```cpp // C++/CLI Wrapper #pragma managed #include "MyCppClass.h" public ref class MyCppWrapper { private: MyCppClass* cppClass; public: MyCppWrapper(int v) { cppClass = new MyCppClass(v); } ~MyCppWrapper() { delete cppClass; } int GetValue() { return cppClass->GetValue(); } }; ``` ```c# // C# 使用 C++/CLI Wrapper class Program { static void Main(string[] args) { MyCppWrapper wrapper = new MyCppWrapper(42); int value = wrapper.GetValue(); Console.WriteLine(value); // 输出 42 } } ``` 在这个示例中,我们创建了一个 C++ 类 `MyCppClass`,并使用 C++/CLI 创建了一个包装器类 `MyCppWrapper`。在 `MyCppWrapper` 中,我们实例化了 `MyCppClass` 的对象,并将其封装在公共成员方法中,以供 C# 调用。 请注意,C++/CLI 项目需要将 `Common Language Runtime Support` 设置为 `/clr`。另外,如果 C++ 类有其他依赖项,需要在 C++/CLI 项目中引用这些依赖项。 使用 C++/CLI 可以方便地在 C#调用 C++ 的类和方法,但需要注意确保 C++ 类的可访问性和正确的函数签名,以便在 C# 中正确使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值