C编写的DLL函数,返回值类型为char *,VB.net如何调用这个函数
我用C编写了一个DLL,其中的函数原型为:char *SectionSteelAW(char const *RawText, unsigned const CtrlCode);
返回值为char *类型。
同时我还用C编写了一个Demo程序,调用这个DLL,是能够正常执行的。
(这个DLL项目及Demo所有源码我已上传到github上,地址为:https://)
但是在程序里,始终不能正常执行,具体表现为:
1、返回值始终是nothing
2、执行此函数后,实参RawText的值会被改变
3、执行几次之后,报错:System.AccessViolationException:“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”
(这个程序所有源码我也已上传到github上,地址为:https://,见分支V2)
请问如何正确调用此函数?
另请问,正确调用此函数后,得到的返回值字符串不需要使用时,如何正确释放内存空间?
(函数内部是通过动态分配内存提供的返回值,由于我的Demo程序是C编写的,可以用free(Resault)来释放。但是中该如何做?)
恳请前辈们不吝赐教!!!
SectionSteelAW函数由于底层实现代码较多,不便全部贴出,仅贴出最终实现代码:
程序代码:
#include "dll.h" #include "calculation.h" #include <string.h> #include <windows.h> DLLIMPORT char *SectionSteelAW(char const *RawText, unsigned const CtrlCode) { char *FormatedText = NULL; char *SecSteType = NULL; char *Resault = NULL; void *obj = NULL; if (formatting(RawText, &FormatedText) == 0) return NULL; SecSteType = getSecSteType(FormatedText); if (SecSteType == NULL) return NULL; obj = NewObj(SecSteType); if (obj == NULL) return NULL; if (SetData(obj, SecSteType, FormatedText) == 0) { FreeObj(&obj, SecSteType); return NULL; } Resault = getResault(obj, SecSteType, CtrlCode); FreeObj(&obj, SecSteType), obj = NULL; free(FormatedText), FormatedText = NULL; //SecSteType来自const字符串数组,不需要释放,只需赋值NULL SecSteType = NULL; return Resault; } BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) { switch(fdwReason) { case DLL_PROCESS_ATTACH: { break; } case DLL_PROCESS_DETACH: { break; } case DLL_THREAD_ATTACH: { break; } case DLL_THREAD_DETACH: { break; } } /* Return TRUE on success, FALSE on failure */ return TRUE; }
C语言Demo程序的具体代码如下:
程序代码:
#include <windows.h> #include <stdio.h> /* #define TYPE_AREA 1 #define TYPE_EXCLUDE_TOPSURFACE 2 #define TYPE_WEIGHT 4 #define METHOD_ROUGHLY 8 #define METHOD_PRECISELY 16 #define METHOD_LOOKUP 32 DLLIMPORT char *SectionSteelAW(char const *RawText, unsigned const CtrlCode); */ typedef char *(*p_SectionSteelAW)(char const *RawText, unsigned const CtrlCode); int main (int argc, char *argv[]) { HMODULE module = NULL; p_SectionSteelAW SSAW = NULL; char *resault = NULL; char RawText[64] = {'\0'}; unsigned ctrlcode = 0; module = LoadLibraryA("SectionSteelAW.dll"); if (module == NULL) { MessageBox(0,"Cannot start this program because of missing \"SectionSteelAW.dll\" file!\n","Error",MB_ICONERROR); return 0; } SSAW = (char *(*)(char const *, unsigned const))GetProcAddress(module, "SectionSteelAW"); if (SSAW == NULL) goto clean; while (scanf("%s %u", RawText, &ctrlcode) != EOF) { resault = SSAW(RawText, ctrlcode); if (resault != NULL) printf("%s\n", resault); free(resault); resault = NULL; } clean: FreeLibrary(module); return 0; }
测试结果是能够正常工作的
输入:H244*175 19
输出:0.244*2+0.175*3-0.007*2
输入:D210*5 33
输出:PI()*0.21
输入:PL500*600*12-PLT120*100*12-PLD150*12 36
输出:(0.5*0.6-0.12*0.5*0.1-PI()*0.075^2)*0.012*7850
这里想插入截图的,不知道怎么插入
程序中的具体应用代码如下(全局变量的赋值修改对此问题没有影响,所以相关代码就不贴出来了):
程序代码:
Module SectionSteelAW Public Const _TESTFLAG = 0 '测试代码控制符 Public Const TYPE_AREA = 1 '计算类型:面积 Public Const TYPE_EXCLUDE_TOPSURFACE = 2 '计算类型:面积子项,扣除顶面 Public Const TYPE_WEIGHT = 4 '计算类型:重量 Public Const METHOD_ROUGHLY = 8 '计算模式:粗略 Public Const METHOD_PRECISELY = 16 '计算模式:精细 Public Const METHOD_LOOKUPINTABLE = 32 '计算模式:查表 Public CTRLCODE As Integer = 0 '控制码 Public Offset_Rows As Integer = 0 '目标行偏移参数 Public Offset_Columns As Integer = 1 '目标列偏移参数 Public Overwrite As Integer = 0 '目标已有数据是否覆盖参数 Public Declare Function SectionSteelAW Lib "SectionSteelAW.dll" (ByVal RawText As String, ByVal CtrlCode As UInteger) As String Public Sub Generate() Dim xlApp As Object = Nothing 'Excel对象 Dim xlWorkbook As Object = Nothing '工作薄对象 'Dim xlSheet As Object = Nothing '工作表对象 Dim xlRange As Object = Nothing '单元格区域 Dim xlCell As Object = Nothing '单元格 Dim sRawText As String = Nothing Dim sResault As String = Nothing Dim starttime As Date Dim endtime As Date '获取Excel程序、工作薄、工作表、选定区域 On Error Resume Next xlApp = GetObject(, "Excel.Application") If Err.Number <> 0 Then Err.Clear() MsgBox("Please open an Excel application first!", vbOKOnly + vbExclamation, "Waring") Exit Sub End If xlWorkbook = xlApp.ActiveWorkbook If xlWorkbook Is Nothing Then MsgBox("Please open an Workbook first!", vbOKOnly + vbExclamation, "Waring") Exit Sub End If xlRange = xlApp.Selection On Error GoTo 0 If _TESTFLAG Then starttime = System.DateTime.Now 'xlApp.screenupdating = False For Each xlCell In xlRange '不覆写且目标不为空时直接跳过 If (Overwrite = 0) And (xlCell.offset(Offset_Rows, Offset_Columns).value IsNot Nothing) Then Continue For sRawText = xlCell.Value sResault = SectionSteelAW(sRawText, CTRLCODE) '输出到Excel If sResault IsNot Nothing Then xlCell.offset(Offset_Rows, Offset_Columns).Value = "=" & sResault '赋值为Nothing是否能正确释放??? sResault = Nothing Else xlCell.offset(Offset_Rows, Offset_Columns).Value = Nothing End If Next 'xlApp.screenupdating = True If _TESTFLAG Then endtime = System.DateTime.Now : MsgBox("执行持续时间:" & (endtime - starttime).ToString) '释放对象内存 xlCell = Nothing : xlRange = Nothing : xlWorkbook = Nothing : xlApp = Nothing End Sub End Module
[此贴子已经被作者于2022-6-21 20:23编辑过]