I have a C++ ATL COM adding that implements some utility functions that refer to the Excel API:
void DoSomething(CComPtr<Excel::Range> &masterCell)
{
// ...
CComPtr<Excel::Range> cell = masterCell->Offset[vertical][horizontal];
// ...
}
When compiling an excel addin for x64 I'm getting lots of spurious errors such as:
cannot convert from 'Excel::Range' to 'ATL::CComPtr<T>'
However, when I compile for Win32 there is no problem. The helper utility functions are not exposed as excel UDF's so I don't think this question is applicable since the function does not have a STDMETHODIMP part.
Any ideas?
Thanks in advance.
CComPtr accepts an interface as a template argument, while Range is dispinterface. You need CComPtr<Excel::IRange> instead.
Doh! Turns out that I was trying to reference a 32-bit excel installation in a 64-bit build:
https://social.msdn.microsoft.com/Forums/en-US/f069ea06-b888-47c0-9ec8-c6cf8a59d9b1/atl-errors-compiling-64bit-com-excel-addin?forum=exceldev
Installing 64-bit excel fixed the issue.
Related
My aim is to create a COM Visible Type that can be imported into VBA (Excel) and consumed there.
The Excel Object Browser can see my class but not any public methods of the class and fails on the attempt at calling a public method.
My F# Code:
namespace DotNetLibrary
type public Class1() =
member public this.DotNetMethod (x:string) = "Hello" + x
In the AssemblyInfo.fs I also amend to [<assembly: ComVisible(true)>]
I run regasm with switches of /codebase /tlb and a .tlb file is generated.
VBA finds my library in the references browser but does not pick up the DotNetMethod defined on Class1 above.
I have tried to follow the C# guidance for this topic in getting to where I am at the moment but I'm not getting to the finish line.
Run-Time Errors
The reason that VBA could not run the method succesfully is because I used the 32-bit version of the regasm utility instead of the 64-bit version to register the type library for COM. Given that I am using 64-bit Excel it needed 64-bit COM type libraries.
Compile-Time Issues
The reason that VBA could not identify the methods in the IDE could be related to the above, but is also likely to be due to the interface issues raised by
#HansPassant in his comments above.
Recently upgraded to a new PC with Win 10 pro, Excel 2016 coming with Office365, vs2015 community. Built a very simple vc++ dll with just one function exported in def file. The code is very simple but would still post here to give a content and make sure there's no problem there.
//also tried __declspec(dllexport) double sumCPP(double a, double b) without .def file
double __stdcall sumCPP(double a, double b)
{
return a + b;
}
'VBA
Public Declare PtrSafe Function sumCpp Lib "C:\MyTestProject\x64\Debug\DllTest.dll" (ByVal a As Double, ByVal b As Double) As Double
But a call from VBA results Run-time error '48': File not found: C:\MyTestProject\x64\Debug\DllTest.dll.
The source code of a more complicated dll project can be built to exe that runs fine, but whose dll prompted this original failure calling dll problem. Any suggestion where to look at? I've tried depends.exe with many supposedly false alarms and dumpbin /dependents but not clear how to use the result. I wonder if this is related to some vs2015 redistributable not in system PATH. I don't see any there but haven't tried to add them yet, as there seem to be too many.
Is there any other option to delegate heavy computation and TCP/IP socket besides using vc++ dll? I don't know but can consider C#, while python would be preferred. Since those dll functions are intended to be called many times in VBA, a system call to vc++ exe doesn't seem to be efficient.
Great thanks in advance!
Since the machine is new so I reset it removing all data. Then I installed Office 2016 64bit and VS Community 2015 from scratch and built the 64bit dll again. This time the error is Run-time error '453' Can't find DLL entry point. Can't find any obvious missing dependent dll by either dumpbin.exe /dependents or depends.exe.
Try change build configuration from "Debug" to "Release"
I'm around trying to create an interoperable dll written in C # for use in Microsoft NAV 2016, for the development of a fiscal printer driver.
In my C # project I called to other functions dll (delivered by the company Bematech, in 32-bit and unmanaged).
Calls to the functions of the dll unmanaged (and tested from an .EXE) I make as follows:
[DllImport ( "BemaFi32.dll")]
public static extern int Bematech_FI_ProgramaAlicuota (Aliquot string, int ICMS_ISS);
When I try to run it from the NAV2016 I get the following error: .A call to "MyAssembly" failed with this message: You are trying to load a program with an incorrect format. Expection from HRESULT: 0x8007000B
I guess the error because the dll is not managed or 32-bit version (if that's the problem becomes more difficult because apparently there is no 64-bit version). Not how to solve the problem.
NAV cannot work with unmanaged code.
The only way is to write a wrapper dll which can be called from NAV.
Microsoft is doing the same with the Office SDK for example...
Cheers!
The problem was not the embedded dll unmanaged, was that the new dll to be 32 bit was not compatible with the client NAV, the solution was to change the 32bit client as follows:
Rename the file to Microsoft.Dynamics.Nav.Client.X64.exe Microsoft.Dynamics.Nav.Client.exe, and then a Microsoft.Dynamics.Nav.Client.X86.exe rename the file to Microsoft.Dynamics.Nav.Client. exe.
and the C / AL change in the variable declared the call to the dll
Property Value
Yes RunOnClient
I ask for a simple vba code to import a C string (null terminated) into Excel 2013 64
I have a C dll (compiled with Visual Studio 2015 for x64, strings set to Multi-byte) which exports several methods like this
__declspec(dllexport) char *MyMsg()
{
return(mymsg);
}
(function body is much more complex)
when working with C, C#, VB net codes etc. I have no problems to call these methods,
some, as C# , may require some additional conversion but methods work and don't crash (most important),
[DllImport(#"D:\my.dll", EntryPoint = "mymsg", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
[return:MarshalAs(UnmanagedType.LPStr)]
internal static extern string ErrMsg()
with old versions of Excel I was able to import as string (stable solution, no problems at all)
however it seems that with Office 2013 developers have modified some things and the old methods now, in Excel 2013 64 (and 2016), can generate exceptions stopping working,
I have tested different vba code (for example the code suggested to import from system dll) with very limited success,
std. debugging tools as Windbg etc. may report memory corruption or equivalent critical exceptions.
I have also considered to modify the C code in order to export a different object but I noticed that Variants in Excel 2013 64 may become very unstable possibly due to different deallocation policy, so I stopped this way,
honestly, as very personal opinion I am reluctant to adopt OLE objects and I would prefer to maintain the actual code in C dll,
your help will be very appreciated,
thanks.
a quick update about this question,
discussing the topic with other developers
I decided to test the way suggested by Microsoft,
calling from VBA and passing a pointer to a String,
herebelow the C code for the two alternatives which I have tested,
I regret to say that in both cases when stressed Excel 2013 64 stops generating an allocation error in VBE7 module (detected by Windbg and Visual Studio 2015)
by the way, the same works fine with Excel 2010 64 and there is little to add...
now, if some microsoft expert can help suggesting a C++ code tested with Excel 2013 64 that will be very appreciated,
differently I would suppose there is something not working as expected (at least in my copy of) Excel 2013 64
__declspec(dllexport) int WINAPI mymsg(BSTR *vbstr)
const char *lpszA = "test Excel 2013 64";
// Alternative 1
// SysFreeString(*vbstr);
// int nLen = MultiByteToWideChar(CP_ACP,0,lpszA,strlen(lpszA),0,0);
// *vbstr = SysAllocStringLen(0,nLen);
// MultiByteToWideChar(CP_ACP,0,lpszA,strlen(lpszA),*vbstr,nLen);
// alternative 2
SysFreeString(*vbstr);
int nLen = strlen(lpszA);
wchar_t *lpszW = new wchar_t[nLen+1];
mbstowcs( lpszW, lpszA, nLen+1);
*vbstr = SysAllocString(lpszW);
delete[] lpszW;
}
I need read data SQLite into Excel. And I found a few solution at (#1, #2). I choose SQLite for Excel of #Govert. My excel is 64bit version, so i've downloaded and replaced sqlite3.dll(32bit) by sqlite3.dll(64bit) then update the VBA declares:
...Declare Function... change to ...Declare PtrSafe Function...
But I'm still cannot run demo Module1.MyTestSQlite in SQLiteForExcel.xls . And error output in VBE Immediate Window:
SQLite3Initialize Error Loading
C:\Users\davuz\Downloads\SQLiteForExcel-0.7\Distribution\SQLite3_StdCall.dll:
193 Error Initializing SQLite. Error: 193
How to fix sqliteforexcel to run with Excel 64bit?
Thank for help?
I (the SQLite for Excel guy) haven't actually tried to figure out the 64-bit VBA declarations yet - I just noted that there is now a pre-compiled SQLite library for 64-bits, which helps us a lot.
First thing to note is that for the 64-bit case you don't need the SQLite3_StdCall.dll intermediate at all. It is just required for 32-bit case where the calling conventions need remapping. So for 64-bit all the .dll references in the VBA file must directly refer to SQLite3.dll.
Next, I think you are on the right track with the PtrSafe changes. But I am not sure exactly how the VBA 64-bit pointers declarations work. One would also have to figure out which of the 'Long' arguments are actually pointers.
So there's still a bit to do...
Edit:
Done. The updated version 0.8 of SQLite for Excel now includes the VBA declarations for 64-bit Excel, updated tests and a copy of the 64-bit SQLite3.dll.