-
C++ Created DLL File To Use In VB6
Wow! It's been a while since I last posted.
It has literally been probably over a decade since I created a DLL file in C++ to use in VB6. However, I want to do an experiment before I even attempt my real method. I created a very basic method in C++ that I compiled into a DLL file:
cpp Code:
#include <iostream>
extern "C" __declspec(dllexport) int AddNumbers(int a, int b)
{
return a + b;
}
Nothing special. Just add two integers and return the result. Compiles into the DLL just fine. And it only contains main.cpp. No headers or anything. The problem is when I try using this in VB6. I move my copied DLL file in with the same directory as my VB6 project and ran this code:
vb6 Code:
Option Explicit
Private Declare Function AddNumbers Lib "Test.dll" (ByVal a As Long, ByVal b As Long) As Long
Private Sub Form_Load()
Dim a As Long
Dim b As Long
Dim result As Long
a = 1
b = 2
result = AddNumbers(a, b)
MsgBox "The result is " & result
End Sub
I end up with an error saying Run-time error '48': File not found.
I compiled it into an exe and ran it. Again, file not found.
I then made efforts to copy the DLL into both the system32 and sysWOW64 directories of Windows. Again, file not found.
I then made the subtle attempt at typing in the full path of the DLL: Private Declare Function AddNumbers Lib "D:\Source Code\VB6\Test.dll" (ByVal a As Long, ByVal b As Long) As Long. Ran the exe, and again, file not found.
So I was like screw it and regsvr32ed all 3 dll files under administrator privilages. Registered just fine. Ran the exe and again... file not found.
I have never had this issue making DLL files before. But, then again, in the past, I was using a much older C++ that required .def files when making DLLs, which is no longer needed to my knowledge. But even so, it cannot find the DLL file to begin with. Tried finding solutions online, with zero luck, and I even went out of my way to get help from both ChatGPT and Google Bard. The AI made attempts to help me but nothing was working. Does anyone have any bright ideas on pulling off what should be simple? Thank you in advance.
-
Re: C++ Created DLL File To Use In VB6
You can use load library to manually load the dll by explicit path first. If loadlibrary fails and the path is right (use a fileexists function first to verify path variable is correct) then it may be the dll is not loading corrrctly because of dependencies or how it’s compiled. Dragging and dropping it on olly dbg would tell you if the dll is loadsbke by a native debugger.
You will also need a __stdcall in your function prototype. This will add some extra chars to the export name even with the extern c. Depending on your vs version there is a pragma export you could use or the best bet is to use a module definition (.def) file to export functions by plain name.
-
Re: C++ Created DLL File To Use In VB6
You should compile x86 (32 bit build).
-
Re: C++ Created DLL File To Use In VB6
I used to have links to a bunch of C - VB projects
This example covers many common tasks:
http://sandsprite.com/openSource.php?id=53
this one is pretty simple too
http://sandsprite.com/tools.php?id=31
-
Re: C++ Created DLL File To Use In VB6
@dz32 -- can you elaborate on 'how it's compiled' leading to a file not found coming from the load process? There's a standing bug holding up some things I want to do where I'm getting that, despite the path being correct (I have a C version with the same name and switch it in and out to test, and the C version loads).
PE viewers show the IAT has imports correctly listed, superficially appearing identical but slightly differing in some nearby bytes under a hex viewer compared to the C version, and there's no runtime loads. Have you encountered something else that would throw a file not found error? (This question isn't VB-specific so I'd also like to hear any causes of this you've encountered in any language, if you indeed have)
-
Re: C++ Created DLL File To Use In VB6
Quote:
Originally Posted by
dz32
You will also need a __stdcall in your function prototype. This will add some extra chars to the export name even with the extern c. Depending on your vs version there is a pragma export you could use or the best bet is to use a module definition (.def) file to export functions by plain name.
__stdcall is required and it will prepend an underscore and append @<number> to function name.
Inside function body you can use #pragma comment(linker, "/EXPORT:" __FUNCTION__"=" __FUNCDNAME__) to undecorate the name without .def file. (It's important to place this inside function for __FUNCTION__ and __FUNCDNAME__ to expand properly)
Most probably you are indeed compiling to an x64 target.
LoadLibrary trick will allow you to place the .dll in any folder (not necessary next to .exe or in PATH) while keeping the declare "pathless" i.e. Private Declare Function AddNumbers Lib "test" (...)
cheers,
</wqw>
-
Re: C++ Created DLL File To Use In VB6
for the "how its compiled" clause thought was a generic catch all. maybe x64, maybe it was compiling as an exe and they had just set the compiled file name as .dll, pe malformation leading to loader failure due to weird project settings, dependencies missing etc. Lots of weird stuff can happen. A borked VS install sometimes even the shared debug vc runtime can not be found.
Not sure I follow the full context on what your running into. Are you compiling in a C obj file into your own VB6 binary and forcing exports from the vb like a standard dll? Hence the ability to switch between that and a C dll?
In other news, I love that pragma, I havent been able to use it with VS2019 for some reason. I used to always use:
#define EXPORT comment(linker, "/EXPORT:"__FUNCTION__"="__FUNCDNAME__)
int __stdcall Funcx() {
#pragma EXPORT
...
this variation seems to have stopped working for me though. worked fine in vs 2008
python source uses the following to create a forwarder, so there must be hope
#define EXPORT_FUNC(name) \
__pragma(comment(linker, "/EXPORT:" DECORATE #name "=" MY_DLL_NAME "." #name))
-
Re: C++ Created DLL File To Use In VB6
More driver stuff. They work fine when the only imports are from ntoskrnl but I'm getting file not found when using imports from fltmgr.sys. The C reference version has the fltmgr imports in it's IAT so I assume that's where it's actually pointing (KMDF, a different framework, uses dynamic loads but those don't appear in the IAT), and the IAT looks identical from a PE viewer.
So since it looked like OP was indeed getting the correct path, I thought it might be a similar issue where a compiler can mess up something in the import table in some subtle way. I've had issues with decorated names before, those give an entry point not found error, so didn't think OP had that issue.
-
Re: C++ Created DLL File To Use In VB6
Yeah export name off is usually a different error. I have 0 clue on the driver world sorry. First guess would be similar to the loadlibrary fail causing the file not found error due to dependency or pe incompatibility of some sort. If DLL main returns 0 the dll can force loadlibrary to fail also I think. So maybe the driver itself is refusing to loaded in a certain manner or only wants one instance of itself in kernel mem and needs a getmodulehandle equilivent instead? Just spitballing
-
Re: C++ Created DLL File To Use In VB6
In the userlsnd world errors in dllmain can also cause the load to fail and be covered up giving misleading errors. DLL main is a unique spot and there are things you are not allowed to do there.
-
Re: C++ Created DLL File To Use In VB6
its the .dll that is not created properly for VB6 to run as many already pointed out.
I use a .dll and I can use it in many ways, without any registration or using loadlibrary.
Code:
Private Declare Function MyFunc Lib "Test.DLL" (ByVal a As Long, ByVal b As Long) As Long
Private Declare Function MyFunc Lib "Test" (ByVal a As Long, ByVal b As Long) As Long
Private Declare Function MyFunc Lib "Test.DAT" (ByVal a As Long, ByVal b As Long) As Long
Private Declare Function MyFunc Lib "Folder\Test" (ByVal a As Long, ByVal b As Long) As Long
Private Declare Function MyFunc Lib "Folder\Test.DAT" (ByVal a As Long, ByVal b As Long) As Long
all the above works. I can even rename the .dll to whatever and even place it in subfolders.
-
Re: C++ Created DLL File To Use In VB6
Quote:
Originally Posted by
dz32
In other news, I love that pragma, I havent been able to use it with VS2019 for some reason.
There is a space before __FUNCDNAME__ which got lost in the forum post
Code:
#pragma comment(linker, "/EXPORT:" __FUNCTION__"=" __FUNCDNAME__)
cheers,
</wqw>
-
Re: C++ Created DLL File To Use In VB6
While this was written for VB5, it works for VB6.
Code:
VB5DLL.TXT
Notes for Developing DLLs for use with
Microsoft (R) Visual Basic (R)
Version 5.00
(C) Copyright Microsoft Corporation, 1996
https://classicvb.net/tips/vb5dll/
This was included on the VB5 installation media.
Joe
-
Re: C++ Created DLL File To Use In VB6
Quote:
Originally Posted by
dz32
Yeah export name off is usually a different error. I have 0 clue on the driver world sorry. First guess would be similar to the loadlibrary fail causing the file not found error due to dependency or pe incompatibility of some sort. If DLL main returns 0 the dll can force loadlibrary to fail also I think. So maybe the driver itself is refusing to loaded in a certain manner or only wants one instance of itself in kernel mem and needs a getmodulehandle equilivent instead? Just spitballing
Was just providing context. If the path is correct, but it's giving a file not found on attempted load, my theory was that the 'not found' was filtering up from a problem in the loader with finding import modules. If my theory was correct, it would explain both my driver issue and OPs DLL issue, being an issue with how the loader processes the import table and not anything specific to drivers. Just a guess, more likely an entirely different issue, but thought it worth asking anyway when you mentioned improper compiling as a source of file not found for attempted load.
-
Re: C++ Created DLL File To Use In VB6
It could be because I forgot to swap it to x86. I am going to test this when I arrive home from work. If it still doesnt work, I will lay out all of the steps and measures I took in great detail and let you guys see if I missed anything. I didn't realize how active the VB6 forum was in 2023 :bigyello:
-
Re: C++ Created DLL File To Use In VB6
I checked and trying to call an x64 dll does indeed produce a file not found error. So that's definitely the leading explanation now if you're not positive it's x86.
No worries though, we've all wasted many an hour missing something obvious :D
-
Re: C++ Created DLL File To Use In VB6
You should also enable relocations in your module (/FIXED:NO).
-
Re: C++ Created DLL File To Use In VB6
Just tried this for fun with the VC++ included in Visual Studio 6 (I've installed it along with VB6, dunno why since I've never used it until now).
I've started with File -> New -> Projects -> Win32 Dynamic-Link Library (seemed like the obvious choice from the list of available projects).
Then added a new C++ Source File:
Test.cpp
Code:
int _stdcall AddNumbers(int a, int b)
{
return a + b;
}
Compiled the project (apparently there are two kinds of builds: Debug and Release, must choose the "Release" build to produce a much smaller DLL), all good, no errors. Then tried to declare it in VB6:
Code:
Private Declare Function AddNumbers Lib "TestDLL\Release\Test.dll" (ByVal a As Long, ByVal b As Long) As Long
This produced an error "Can't find entry point for function AddNumbers in Test.dll". Apparently the C++ project needed another text file where you could specify which functions are exported:
Test.def
Code:
LIBRARY Test
EXPORTS
AddNumbers @1
Compiled it again and now everything worked as expected. :D
-
Re: C++ Created DLL File To Use In VB6
humm that pragma worked in a clean project with 2019 again. Last project I was trying it in just would not work, it was killing me. No idea. Gremlins!
-
Re: C++ Created DLL File To Use In VB6
Quote:
Originally Posted by
The trick
You should compile x86 (32 bit build).
Well I'll be a son of a gun, it worked! I didn't even need to change the code or use regsvr32 or anything. With that said, I need to attempt my real method in C++:
cpp Code:
#include <iostream>
#include <Windows.h>
extern "C" {
__declspec(dllexport) DWORD NvOptimusEnablement;
__declspec(dllexport) void EnableGeForce() {
NvOptimusEnablement = 0x00000001;
}
__declspec(dllexport) void DisableGeForce() {
NvOptimusEnablement = 0x00000000;
}
}
What this will do is in my DirectX applications, it will tell the NVidia Optimus drivers to switch the GeForce GTX or RTX video card from using integrated graphics (which it does by default) to using discrete graphics, causing the application to run 4x to 5x faster than usual. VB6 alone cannot do this, but this should trigger it through the dll.
[EDIT] Crap, that didn't work. :mad: The methods did nothing in my VB6 app. Gonna have to try something else. The real way is like so:
cpp Code:
extern "C"
{
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}
This works on C++ apps that use DirectX, OpenGL, or Vulkan.
-
Re: C++ Created DLL File To Use In VB6
Why do you think VB can't do it? You've missed a lot. There's vb6 kernel drivers now. What you're doing looks like a directx/dxgi thing. You can use my oleexp typelib which covers d3d11, d3d12, dxgi, direct2d, directwrite, directcompositiob, WIC, etc. Another member has a demo of using OpenCL for GPU based computing in vb6.
Absolute worst case scenario of "vb6 can't do it" is needing an assembly thunk, besides that narrow case of things that can't be done in 32bit at all. But your 32bit DLL would have the same issue. And those problems are largely solvable by twinBASIC, which is getting very close to full backwards compatible while adding a laundry list of modern language features like 64bit compilation.
If you can't force adding a variable export through the linker you could patch the table in the pe header.
From what I read a DLL won't work for that anyway -- but as an alternative, some nvapi DLL calls will. Didn't check callconv, but the trick has a patch for vb6 that fixes it (ever noticed the cdecl keyword is highlighted?)
-
Re: C++ Created DLL File To Use In VB6
VB6 won't be able to do this:
extern "C"
{
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}
which is why I am attempting it through a dll. Doing this one line will trigger the Nvidia Optimus driver, but so far only through C++ which is weird. Like nothing in the C++ project will have anything Nvidia related but somehow the driver magically recognizes it when you do this one line of code. Magically making it happen in VB6 is gonna take some hacks.
-
Re: C++ Created DLL File To Use In VB6
It seems that the Matrix has restarted and a new cycle has begun: How to use a _declspec(dllexport) in VB6?
-
Re: C++ Created DLL File To Use In VB6
Quote:
Originally Posted by
VanGoghGaming
Yeah that was me attempting it 3 years ago. I'm back at trying to crack the code... Matrix style :bigyello:
-
Re: C++ Created DLL File To Use In VB6
in direct2d I can initialize it with software or hardware.
hardware will use gpu memory while software will use cpu memory.
Im not sure what this Optimus means but its strange that u need c++ for it to start.
so, u have 2 gpu cards connected to 2 different monitors?
-
Re: C++ Created DLL File To Use In VB6
Quote:
Originally Posted by
baka
in direct2d I can initialize it with software or hardware.
hardware will use gpu memory while software will use cpu memory.
Im not sure what this Optimus means but its strange that u need c++ for it to start.
so, u have 2 gpu cards connected to 2 different monitors?
No baka. This is one monitor, and one video card. If you have a NVidia-based graphics card on your PC or laptop, then you have the Nvidia Optimus driver as well. Let's say you built an app, and are using DirectX, OpenGL, or Vulkan and you are using the hardware to process graphics. Sure, your app may run 60 FPS and can rotate cubes or even worlds like nothing, but believe it or not, you are using integrated graphics processing by default and not discrete graphics processing from your GTX or RTX card. That means you haven't unlocked its true potential. That is where this line of code comes in:
cpp Code:
extern "C"
{
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}
The NvOptimusEnablement variable is a global variable that is used by the NVIDIA Optimus driver to determine whether to use the integrated graphics or the dedicated graphics. When the value of the NvOptimusEnablement variable is 1, the NVIDIA Optimus driver will use the dedicated graphics. When the value of the NvOptimusEnablement variable is 0, the NVIDIA Optimus driver will use the integrated graphics.
The NVIDIA Optimus driver looks for the NvOptimusEnablement variable in the export table of the DLL. If the NvOptimusEnablement variable is found in the export table, the NVIDIA Optimus driver will use the value of the variable to determine whether to use the integrated graphics or the dedicated graphics.
The __declspec(dllexport) attribute is used to mark functions and variables that are to be exported from a DLL. When a function or variable is marked with the __declspec(dllexport) attribute, the function or variable is added to the export table of the DLL.
The export table is a table that contains the names and addresses of the functions and variables that are exported from a DLL. When a program loads a DLL, the program can use the export table to find the addresses of the functions and variables that are exported from the DLL.
In the case of the NvOptimusEnablement variable, the __declspec(dllexport) attribute is used to add the variable to the export table of the DLL. When the NVIDIA Optimus driver loads the DLL, the NVIDIA Optimus driver can use the export table to find the address of the NvOptimusEnablement variable. The NVIDIA Optimus driver can then use the value of the NvOptimusEnablement variable to determine whether to use the integrated graphics or the dedicated graphics.
In summary, the NvOptimusEnablement variable is a global variable that is used by the NVIDIA Optimus driver to determine whether to use the integrated graphics or the dedicated graphics. The __declspec(dllexport) attribute is used to add the NvOptimusEnablement variable to the export table of the DLL. When the NVIDIA Optimus driver loads the DLL, the NVIDIA Optimus driver can use the export table to find the address of the NvOptimusEnablement variable. The NVIDIA Optimus driver can then use the value of the NvOptimusEnablement variable to determine whether to use the integrated graphics or the dedicated graphics. As a result, your graphics-based application will run at significantly higher speeds and handle a lot more polygons, post-processing effects, and so on.
As an added bonus, your application will have this tab pop up at the very beginning telling you that it has been unlocked and tell you to press Alt+Z to use the GeForce Experience overlay. Practically pops up in just about all of my triple A game titles as well.
Look to the right side of this image to see the tab:
http://www.vbforums.com/attachment.p...1&d=1588662156
-
Re: C++ Created DLL File To Use In VB6
Would it be looking for that export from the main exe only?
https://docs.nvidia.com/gameworks/co...op/optimus.htm
In c you can create exports for exes as well. There are ways to link in C object files into vb6 executables, since it’s the vc6 linker you can probably force exports from vb6 executables as well . You might be able to force the static dll bindings into the import table which sounds like would also enable it. Or find a way to auto configure the profile settings.
Maybe the easiest thing is to minimally modify a version of upx to do the export then you can arbitrarily apply it to anything.
-
Re: C++ Created DLL File To Use In VB6
Well I had no choice but to use an exe just to run the DLL that was in the same directory as the executable. I will try something else tomorrow.
-
Re: C++ Created DLL File To Use In VB6
As I mentioned some brief research indicates there's APIs in nvapi.dll that will accomplish the same thing as the export, and that putting the export in a dll will not work.
But more to the point... you could write a initialization routine that on the first load of your exe, patches it into the export table by making a copy of the exe first then doing it on the copy. The api is a better alternative obviously, but there's *always* a workaround for every besides 'has to be x64 itself'.
It may seem crazy but give this simple solution a try if you haven't:
Code:
Public Declare Function LoadLibraryA Lib "kernel32" (ByVal lpLibFileName As String) As Long
Private m_hNV As Long
Sub Main()
m_hNV = LoadLibrary("nvapi.dll")
'Continue to load app
Obviously you'll want sub main as your startup location.
This is based on how the workaround for C# appears to work and my guess that's what a Chinese post in VB is doing with that call.
Edit: If the above doesn't work, I found a slightly more difficult way that very likely will that's still substantially easier than implementing the nvpatch export table method...
Code:
Private m_hNV As Long
Private Declare Function NvAPI_QueryInterface Lib "nvapi.dll" (ByVal pfn As Long) As Long
Private Declare Function DispCallFunc Lib "oleaut32.dll" ( _
ByVal pvInstance As Long, _
ByVal FuncAddr As Long, _
ByVal CallConvention As Integer, _
ByVal rtnType As VbVarType, _
ByVal FuncArgsCnt As Long, _
ByRef FuncArgTypes As Any, _
ByRef FuncArgVarAddresses As Any, _
ByRef FuncResult As Any) As Long
Sub Main()
m_hNV = LoadLibrary("nvapi.dll")
Dim lpInit As Long 'NvAPI_Initialize
lpInit = NvAPI_QueryInterface(&H0150E828)
Dim lRet As Long
DispCalFunc 0, lpInit, CC_STDCALL, vbLong, 0, ByVal 0, ByVal 0, lRet
I haven't checked my call by pointer code, or the calling convention (above works for stdcall but if it's cdecl you'd need to adjust both calls, the first with The trick's CDeclFix patch), but the main point is, you obtain a pointer to NvAPI_Initialize and call it by pointer. It would look like Function NvAPI_Initialize() As Long.
ETA: Breaking news, twinBASIC already supported function exports simply by placing [ DllExport ] before a function, it now supports exporting constants the same way. (The attribute is [ DllExport ] but it works in exes too). (I mention tB in the VB6 forum because it's highly relevant when you can open a vbp and click run, barring bugs and a few outstanding unimplemented features while it's in beta)
https://www.vbforums.com/images/ieimages/2023/10/18.jpg
-
Re: C++ Created DLL File To Use In VB6
I asked Poe, here what I got:
Code:
Declare Function NvAPI_Initialize Lib "nvapi.dll" () As Long
Declare Function NvAPI_EnumPhysicalGPUs Lib "nvapi.dll" (ByRef gpuHandles As Long, ByRef gpuCount As Long) As Long
Declare Function NvAPI_GPU_SetEDID Lib "nvapi.dll" (ByVal gpuHandle As Long, ByVal displayPath As Long) As Long
```
Public Sub EnableNvOptimus()
Dim nvapiInitResult As Long
Dim gpuHandles(1 To 10) As Long ' Adjust the array size as per your requirement
Dim gpuCount As Long
nvapiInitResult = NvAPI_Initialize()
If nvapiInitResult = 0 Then
NvAPI_EnumPhysicalGPUs VarPtr(gpuHandles(1)), gpuCount
If gpuCount > 0 Then
NvAPI_GPU_SetEDID gpuHandles(1), 0 ' Set the displayPath parameter as per your requirement
End If
End If
End Sub
now Im not sure if this works.
also asked about it and here the answer:
Quote:
When using Direct2D, the NvOptimusEnablement setting is not directly applicable because it specifically pertains to NVIDIA Optimus technology, which is primarily used for switching between integrated and discrete GPUs on laptops to optimize power consumption. Since Direct2D runs primarily on the GPU, it already leverages the power of the GPU for rendering, regardless of whether you choose hardware or software mode.
In hardware mode, Direct2D will utilize the GPU for rendering, which can provide faster performance and take advantage of GPU memory. This mode is usually recommended for most scenarios, especially if your system has a dedicated GPU.
In software mode, Direct2D operates using the CPU and system memory for rendering. While it may be useful in certain situations, such as when you don't have a dedicated GPU or need to perform specific CPU-based operations, it generally results in slower performance compared to hardware mode.
In summary, when using Direct2D, you can choose between hardware and software modes based on your specific requirements. NvOptimusEnablement is not directly applicable to Direct2D, as it is primarily relevant to GPU switching on laptops.
-
1 Attachment(s)
Re: C++ Created DLL File To Use In VB6
Create a small ASM file with content:
Code:
format MS COFF
public NvOptimusEnablement
section '.text' code readable executable
NvOptimusEnablement dd 1
Use FASM to compile it (or use the precompiled OBJ file from the attachment).
Open your VBP file in the notepad and add following lines:
Code:
[VBCompiler]
LinkSwitches=-EXPORT:NvOptimusEnablement nvidia.obj
(nvidia.obj - the name of your produced FASM file).
Now you can open your VBP file and compile it in VB6 - the executable will contain needed export.
-
Re: C++ Created DLL File To Use In VB6
@baka, nvapi.dll has only one export: NvAPI_QueryInterface. You supply a code to it, it returns a function pointer. You'd have to call the 3 you mentioned (if initialize doesn't work alone, which I believe it does), like my example in my last post.
As usual though, I think The trick has the best answer. :)
-
Re: C++ Created DLL File To Use In VB6
Quote:
Originally Posted by
The trick
Create a small ASM file with content:
Code:
format MS COFF
public NvOptimusEnablement
section '.text' code readable executable
NvOptimusEnablement dd 1
Use
FASM to compile it (or use the precompiled OBJ file from the attachment).
Open your VBP file in the notepad and add following lines:
Code:
[VBCompiler]
LinkSwitches=-EXPORT:NvOptimusEnablement nvidia.obj
(nvidia.obj - the name of your produced FASM file).
Now you can open your VBP file and compile it in VB6 - the executable will contain needed export.
Interesting. Might do the trick. No pun intended. :lol:
I'll be home soon to attempt this.
-
Re: C++ Created DLL File To Use In VB6
Quote:
Originally Posted by
Jacob Roman
I didn't realize how active the VB6 forum was in 2023 :bigyello:
Yup we're still here :). VB6 forever!!!
-
Re: C++ Created DLL File To Use In VB6
Im back. Sorry got busy. Nope. The assembly bit was a good idea, but it didn't work.
-
Re: C++ Created DLL File To Use In VB6
Quote:
Originally Posted by
baka
I asked Poe, here what I got:
Code:
Declare Function NvAPI_Initialize Lib "nvapi.dll" () As Long
Declare Function NvAPI_EnumPhysicalGPUs Lib "nvapi.dll" (ByRef gpuHandles As Long, ByRef gpuCount As Long) As Long
Declare Function NvAPI_GPU_SetEDID Lib "nvapi.dll" (ByVal gpuHandle As Long, ByVal displayPath As Long) As Long
```
Public Sub EnableNvOptimus()
Dim nvapiInitResult As Long
Dim gpuHandles(1 To 10) As Long ' Adjust the array size as per your requirement
Dim gpuCount As Long
nvapiInitResult = NvAPI_Initialize()
If nvapiInitResult = 0 Then
NvAPI_EnumPhysicalGPUs VarPtr(gpuHandles(1)), gpuCount
If gpuCount > 0 Then
NvAPI_GPU_SetEDID gpuHandles(1), 0 ' Set the displayPath parameter as per your requirement
End If
End If
End Sub
now Im not sure if this works.
also asked about it and here the answer:
Nope. It can't find the DLL entry point NVAPI_Initialize
-
Re: C++ Created DLL File To Use In VB6
Quote:
Originally Posted by
Jacob Roman
Nope. It can't find the DLL entry point NVAPI_Initialize
See my posts above and below that addressing this. You need to call it by pointer obtained from NvAPI_QueryInterface, the one function nvapi.dll exports.
ETA: My code was slightly off. First, it appears nvapi.dll uses cdecl, and names are case sensitive and I had the case wrong.
Code:
Private m_hNV As Long
Private Declare Function nvapi_QueryInterface CDecl Lib "nvapi.dll" (ByVal pfn As Long) As Long
Private Declare Function DispCallFunc Lib "oleaut32.dll" ( _
ByVal pvInstance As Long, _
ByVal FuncAddr As Long, _
ByVal CallConvention As Integer, _
ByVal rtnType As VbVarType, _
ByVal FuncArgsCnt As Long, _
ByRef FuncArgTypes As Any, _
ByRef FuncArgVarAddresses As Any, _
ByRef FuncResult As Any) As Long
Sub Main()
m_hNV = LoadLibrary("nvapi.dll")
Dim lpInit As Long 'NvAPI_Initialize
lpInit = NvAPI_QueryInterface(&H0150E828)
Dim lRet As Variant
DispCalFunc 0, lpInit, CC_CDECL, vbLong, 0, ByVal 0, ByVal 0, lRet
Then the result is CLng(lRet). Forgot VB doesn't do that conversion for you.
So you'll need The trick's CDeclFix addin for VB6 in order for the CDecl keyword to work in the API declare.
-
Re: C++ Created DLL File To Use In VB6
Quote:
Originally Posted by
Jacob Roman
Im back. Sorry got busy. Nope. The assembly bit was a good idea, but it didn't work.
Attach the produced executable.
-
1 Attachment(s)
Re: C++ Created DLL File To Use In VB6
Here ya go. Good luck. :P
-
Re: C++ Created DLL File To Use In VB6
DirectX8 doesn't support this. Use DirectX9 and above instead.