调用第三方动态库出现access voilation错误,如何解决?

twtyypmb123 2018-10-11 06:21:19
自己项目是c#,项目需要调用第三方dll,奇怪的是在用dllimport引入后调用其中的某些方法时就报了标题上的错,但是对方提供的demo就没有问题,想到是不是C#不支持这个dll?于是就用vs建立c++项目调用试一下,也出现同样问题,再后来直接祭出codeblocks用纯C++,居然成功了,这难道是微软的bug?


...全文
240 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
twtyypmb123 2018-12-22
  • 打赏
  • 举报
回复
引用 9 楼 xian_wwq 的回复:
[quote=引用 7 楼 x3230835 的回复:] 这是用codeblocks写的纯C++版本,这个不会报错

#include <iostream>
#include "windows.h"
#include "stdio.h"

using namespace std;
typedef int (*INIT)();
typedef int (WINAPI *BUS)(char*,char[]);


int main(int argc,char **argv)
{
    HINSTANCE hDllInst = LoadLibrary("soft.dll");
	INIT Init = (INIT)GetProcAddress(hDllInst, "INIT");
	BUS Bus = (BUS)GetProcAddress(hDllInst, "BUSINESS_HANDLE");
	char* input = "31";
	char output[1024];
	Init();
	Bus(input,output);
	cout<<output<<endl;
	cin.get();
	return 0;
}

1.凡涉及char*类型的 DllImport最好显式声明字符集,使用Ansi 2.看c++的代码,char output[1024]; 分配的空间足够,所以正常。 而C#的Stringbuilder没有分配空间,可能就越界了。 [/quote] 奇就奇在同样的代码,纯C++没事,VC++就有问题
xian_wwq 2018-11-20
  • 打赏
  • 举报
回复
引用 7 楼 x3230835 的回复:
这是用codeblocks写的纯C++版本,这个不会报错

#include <iostream>
#include "windows.h"
#include "stdio.h"

using namespace std;
typedef int (*INIT)();
typedef int (WINAPI *BUS)(char*,char[]);


int main(int argc,char **argv)
{
HINSTANCE hDllInst = LoadLibrary("soft.dll");
INIT Init = (INIT)GetProcAddress(hDllInst, "INIT");
BUS Bus = (BUS)GetProcAddress(hDllInst, "BUSINESS_HANDLE");
char* input = "31";
char output[1024];
Init();
Bus(input,output);
cout<<output<<endl;
cin.get();
return 0;
}



1.凡涉及char*类型的
DllImport最好显式声明字符集,使用Ansi

2.看c++的代码,char output[1024]; 分配的空间足够,所以正常。
而C#的Stringbuilder没有分配空间,可能就越界了。
stherix 2018-11-19
  • 打赏
  • 举报
回复
一. sb要先预分配空间 二. 用cdecl看看,默认是stdcall
twtyypmb123 2018-11-19
  • 打赏
  • 举报
回复
这是用codeblocks写的纯C++版本,这个不会报错

#include <iostream>
#include "windows.h"
#include "stdio.h"

using namespace std;
typedef int (*INIT)();
typedef int (WINAPI *BUS)(char*,char[]);


int main(int argc,char **argv)
{
    HINSTANCE hDllInst = LoadLibrary("soft.dll");
	INIT Init = (INIT)GetProcAddress(hDllInst, "INIT");
	BUS Bus = (BUS)GetProcAddress(hDllInst, "BUSINESS_HANDLE");
	char* input = "31";
	char output[1024];
	Init();
	Bus(input,output);
	cout<<output<<endl;
	cin.get();
	return 0;
}

twtyypmb123 2018-11-19
  • 打赏
  • 举报
回复
引用 5 楼 xian_wwq 的回复:
[quote=引用 4 楼 x3230835 的回复:] [quote=引用 2 楼 xian_wwq 的回复:] access voilation的错误大多与指针操作有关 操作了空指针或数组越界就会报此类错误 比如返回的char* 不能用string,必须使用stringbuilder, 且stringbuilder需要预先分配空间
方法原型定义为Foo(const char*,char *),试过了stringbuilder,甚至byte[],依然是一样的错误[/quote] 第一个char使用string,第二个使用stringbuilder 上代码看看 [/quote]

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

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        /// <summary>
        /// 初始化
        /// </summary>
        /// <returns></returns>
        [DllImport("soft.dll")]
        static extern int INIT();
        /// <summary>
        /// 接口
        /// </summary>
        /// <param name="inputData"></param>
        /// <param name="outputData"></param>
        /// <returns></returns>
        [DllImport("soft.dll")]
        static extern int BUSINESS_HANDLE(StringBuilder inputData, StringBuilder outputData);
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        private void button1_Click(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            int i = INIT();
            i = BUSINESS_HANDLE(new StringBuilder("31"), sb);//这一步出现问题
        }
    }
}
xian_wwq 2018-10-16
  • 打赏
  • 举报
回复
引用 4 楼 x3230835 的回复:
[quote=引用 2 楼 xian_wwq 的回复:]
access voilation的错误大多与指针操作有关
操作了空指针或数组越界就会报此类错误
比如返回的char*
不能用string,必须使用stringbuilder,
且stringbuilder需要预先分配空间

方法原型定义为Foo(const char*,char *),试过了stringbuilder,甚至byte[],依然是一样的错误[/quote]
第一个char使用string,第二个使用stringbuilder
上代码看看
xian_wwq 2018-10-15
  • 打赏
  • 举报
回复
access voilation的错误大多与指针操作有关
操作了空指针或数组越界就会报此类错误
比如返回的char*
不能用string,必须使用stringbuilder,
且stringbuilder需要预先分配空间
twtyypmb123 2018-10-15
  • 打赏
  • 举报
回复
引用 2 楼 xian_wwq 的回复:
access voilation的错误大多与指针操作有关 操作了空指针或数组越界就会报此类错误 比如返回的char* 不能用string,必须使用stringbuilder, 且stringbuilder需要预先分配空间
方法原型定义为Foo(const char*,char *),试过了stringbuilder,甚至byte[],依然是一样的错误
twtyypmb123 2018-10-15
  • 打赏
  • 举报
回复
引用 1 楼 stherix 的回复:
bug是不可能的 往往是数据类型没有对应上,或者是字符集不一致引起的 你首先要把dll方法签名和你c#里面的import写出来 别人才能告诉你哪里出了问题
字符集和调用约定的所有组合关系已经试过,报错信息相同
stherix 2018-10-12
  • 打赏
  • 举报
回复
bug是不可能的 往往是数据类型没有对应上,或者是字符集不一致引起的 你首先要把dll方法签名和你c#里面的import写出来 别人才能告诉你哪里出了问题

110,545

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧