转一段C代码(dll中的qsort函数)到VB代码

sxqvb 2018-10-29 11:02:22
现在已经可以通过dl调用qsort这个函数,但不知道在VB里怎么用
#include<stdio.h>
#include<stdlib.h>
int comp(const void*a,const void*b)
{
return *(int*)a-*(int*)b;
}
int main()
{
int i=0;
int *array;
int n;
scanf("%d",&n);
array=(int*)malloc(n*sizeof(int));

for(;i<n;i++)
{
scanf("%d",(array+i));
}
qsort(array,n,sizeof(int),comp);
for(i=0;i<n;i++)
{
printf("%d\t",array[i]);
}
return 0;
}
...全文
308 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
脆皮大雪糕 2018-10-31
  • 打赏
  • 举报
回复
引用 15 楼 Chen8013 的回复:
[
你是太粗心,还是眼神不好 ?
这些“关键内容”你都没看见……

好吧,我的错
舉杯邀明月 2018-10-31
  • 打赏
  • 举报
回复
引用 13 楼 chewinggum 的回复:
[quote=引用 12 楼 Chen8013 的回复:]
简单的“调用示例”代码如下(示例工程中有此代码),
那个接口模块 modQSort的代码这儿就不贴了,反正没有我的那个tlb,有模块代码也无用。


就烦你这种嘚瑟一堆不留关键内容的[/quote]

你是太粗心,还是眼神不好 ?
这些“关键内容”你都没看见……
舉杯邀明月 2018-10-31
  • 打赏
  • 举报
回复
引用 13 楼 chewinggum 的回复:
[quote=引用 12 楼 Chen8013 的回复:]
简单的“调用示例”代码如下(示例工程中有此代码),
那个接口模块 modQSort的代码这儿就不贴了,反正没有我的那个tlb,有模块代码也无用。


就烦你这种嘚瑟一堆不留关键内容的[/quote]
晕死!
我都说了已经把整个示例工程发出来了……


上面那张图片,直接另存了 WinRAR文档,然后打开、解压,
 这些“关键内容”都在里面!!!
脆皮大雪糕 2018-10-31
  • 打赏
  • 举报
回复
引用 12 楼 Chen8013 的回复:
简单的“调用示例”代码如下(示例工程中有此代码),
那个接口模块 modQSort的代码这儿就不贴了,反正没有我的那个tlb,有模块代码也无用。


就烦你这种嘚瑟一堆不留关键内容的
舉杯邀明月 2018-10-31
  • 打赏
  • 举报
回复
呵呵,也许你会感兴趣的事情 … 多着呢 …………

sxqvb 2018-10-31
  • 打赏
  • 举报
回复
,厉害,看来还有很多东西要学
话说我又开始对你那个图片藏文件感性趣了
舉杯邀明月 2018-10-31
  • 打赏
  • 举报
回复
引用 8 楼 sxqvb 的回复:
我看了网上说stdcall和cdecl的主要区别是 清理栈方式,stdcall是被调用函数清理(函数自己清理),cdecl是调用者清理
我上面的atoi和sin是cdecl调用方式,并且只有一个参数,所以提示dll调用约定错误,生成exe后可以正常运行没有绷溃
我调用qsort后绷溃了,是不是因为qsort有多个参数,栈要自己清理的原因,如果是要怎么作呢高手


崩溃的原因,不是“因为要自己清栈”,也不是因为“多个参数”……
而是因为你提供的“回调函数”不合约定。


舉杯邀明月 2018-10-30
  • 打赏
  • 举报
回复
这有什么“好玩”的 ……
不就是因为它是 CDecl调用约定的吗!


VB6中用点技巧“包装一下”,就可以调用了。
sxqvb 2018-10-30
  • 打赏
  • 举报
回复
说的没错,但我现在感性趣的正是怎么调用公共库
脆皮大雪糕 2018-10-30
  • 打赏
  • 举报
回复
费那么大的劲讨论调用公共库,VB版的快速排序都已经实现完加优化两轮了。
考虑有多少排序量,量不大的话,VB配合现在的CPU,就算效率比C比汇编低,你也感觉不出差异。用C和汇编节约出来的时间,你也干不出啥别的事情。
sxqvb 2018-10-30
  • 打赏
  • 举报
回复
我看了网上说stdcall和cdecl的主要区别是 清理栈方式,stdcall是被调用函数清理(函数自己清理),cdecl是调用者清理
我上面的atoi和sin是cdecl调用方式,并且只有一个参数,所以提示dll调用约定错误,生成exe后可以正常运行没有绷溃
我调用qsort后绷溃了,是不是因为qsort有多个参数,栈要自己清理的原因,如果是要怎么作呢高手
舉杯邀明月 2018-10-30
  • 打赏
  • 举报
回复
引用 10 楼 sxqvb 的回复:
说的没错,但我现在感性趣的正是怎么调用公共库


呵呵,实现方法,我已经在4楼说了。
并且还有一种方法,就是用C++另写一个StdCall 的dll作为“二传手”,
 去调用CDecl调用约定的API(这种方法就会“增加1个dll文件”了)。


我在4楼说的“用轻量级COM对象调用qsort( )”的方法,不妨给你看看。
下面这张图片,另存为“WinRAR文档”,就可以解压出我的“示例”代码了。
注意,建议用WinRAR、好压等压缩软件打开,
  目前已知“数字流氓”那个二百五软件(360压缩)是不能识别我这个文档的。
这是一个完整的VB6工程,有“应用示例”代码,并且所需的tlb文件也在里面的。
注意,要运行这个工程,就必须引用类型库“ VB6 快速排序过程接口”,
  如果打开我的工程后,运行时 IQSort 出现“类型未定义”提示,
  自己再手动引用一下:“工程”→“引用”,然后点“浏览”打开我的那个tlb 文件。


简单的“调用示例”代码如下(示例工程中有此代码),
那个接口模块 modQSort的代码这儿就不贴了,反正没有我的那个tlb,有模块代码也无用。
Option Explicit

Private Sub Command1_Click()
Dim arrData() As Long
Dim i&, k As Long

Me.Cls
If (CreateQSort()) Then
Me.Print "接口对象创建失败。"
Else
Me.Print "接口对象创建成功。"
k = 15&
Call Randomize
ReDim arrData(k)
For i = 0& To k
arrData(i) = 5000& * Rnd()
Next
Call QuickSort(arrData(), 0&, k)
For i = 0& To k
Me.Print i; arrData(i)
Next
End If
End Sub

Private Sub Command2_Click()
Dim arrData() As Long
Dim fTime!, lNum&, i&

lNum = Val(Text1.Text)
If (5& > lNum) Then lNum = 5&
lNum = 10000& * lNum - 1&
Me.Cls
Call Randomize
Call CreateQSort
ReDim arrData(lNum)
DoEvents
fTime = Timer
For i = 0& To lNum
arrData(i) = &H3FFFFFF * Rnd()
Next
Me.Cls
Me.Print "数据总数: "; i \ 10000&; "万个"
Me.Print "产生数据耗时:"; Format$(Timer - fTime, "0.00") & "秒"
DoEvents
fTime = Timer
Call QuickSort(arrData(), 0&, lNum)
Me.Print "数据排序耗时:"; Format$(Timer - fTime, "0.00") & "秒"
End Sub
脆皮大雪糕 2018-10-30
  • 打赏
  • 举报
回复
省心的办法是用C封装一个调用代理DLL,暴露stdcall的接口给VB,参数传入转一手cdecl调用公共库,结果再返回来给VB。
十五分钟搞定,而且没有什么调试环境完蛋编译OK,什么一个参数两个参数的问题。
不要勉强98年的VB做一些他做不到的事情,节省下来的时间,全身心投入社会主义现代化建设。
sxqvb 2018-10-29
  • 打赏
  • 举报
回复
这是qsort的定义,应该就C语自带的那个。
Private Declare Function qsort Lib "NTDLL.DLL" (base As Long, ByVal nelem As Long, ByVal width As Long, ByVal fcmp As Long) As Long
sxqvb 2018-10-29
  • 打赏
  • 举报
回复
给你们看一个好玩的,要编译成exe后才能看到效果,你们试一下qsort这个函数怎么用。

Private Declare Function atoi Lib "ntdll" (ByVal str As String) As Long                  '字符串转换到整型数
Private Declare Function sin1 Lib "ntdll" Alias "sin" (ByVal numn As Double) As Double 'sin

Private Sub Command1_Click()

Dim a As Long
Dim b As String

b = "123.456"
a = atoi(b)
MsgBox a

'----------------------

Dim c, d As Single
c = 1
d = sin1(c)
MsgBox d

End Sub
舉杯邀明月 2018-10-29
  • 打赏
  • 举报
回复
引用 2 楼 sxqvb 的回复:
请教这段怎么转成VB的
int comp(const void*a,const void*b)
{
return *(int*)a-*(int*)b;
}


这段C++代码,在VB6中可以这样写:
function comp(a as long , b as long) as long
comp = a-b
end function


1. 网上有按照“快速排序”原理编写的VB代码,
  并不是说一定得按C代码的模型“翻译”成VB代码。

2. VB6中,可以按“汇编代码 + CallWindowProc”的形式,
    去调用系统中VC运行库中的qsort( )接口函数。
  (因为这个函数是CDecl调用约定的,VB6中不能直接调用)

3. 可以用“TLB + 轻量级COM对象”的形式(当然也离不开“汇编”),
    去调用系统中VC运行库中的qsort( )接口函数。
  此方法比前一个方法运行效率高一些(调用CallWindowProc( )会多绕很多弯路),
 但实现起来要麻烦些。
   当然在“每次处理数理量都很大”时、或者调用不太频繁时,效率提升就不明显了,
 毕竟“耗时”主要在排序处理上了,调用CallWindowProc( ) 造成“多出的开销”相比之下可以忽略。
脆皮大雪糕 2018-10-29
  • 打赏
  • 举报
回复
a,b是一个指针变量
int* 是类型说明
()是强制转换运算符
(int *)a是表示把a强制转换成一个int型的指针。
*(int *)a就是取a指向的内容的意思
return *(int*)a-*(int*)b;
就是返回a b两个地址中的 整型 数据 的差!
sxqvb 2018-10-29
  • 打赏
  • 举报
回复
请教这段怎么转成VB的
int comp(const void*a,const void*b)
{
return *(int*)a-*(int*)b;
}
脆皮大雪糕 2018-10-29
  • 打赏
  • 举报
回复
快速排序,随便搜一下,遍地都是代码,要什么语言有什么语言的。
VB6的参考
http://outofmemory.cn/code-snippet/2643/VB-release-quick-paixusuanfa-code

1,486

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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