c "swprintf_s" access violation - c

I am trying to generate some file names automatically. The following was working:
unsigned int fileCounter()
{
static unsigned int fileNo = 0;
return fileNo++;
}
void createFile(WCHAR* sourceName)
{
static const WCHAR wSpec[] = L"c:/test/%s%3u.bmp";
WCHAR wFileName[MAX_PATH];
swprintf_s(wFileName, MAX_PATH, wSpec, sourceName, fileCounter());
}
// called by
createFile(TEXT("somename"));
I tried to separate the above function into a separate dll project (where the createFile function is exported, using the typical
#ifdef MY_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif
MY_API void createFile(WCHAR* sourceName);
in the header file included in the source caller, and I get an access violation error on the swprintf_s
I have tried to replace with the "unsafe" version, but I get the same error. (same if I used the sprintf_s and CHAR* variables)
Also have tried (suggested in a similar question)
swprintf_s(wFileName, _countof(wFileName), wSpec, sourceName, fileCounter());
I still get
(5ec.4d4): Access violation - code c0000005 (first chance)
I can't figure out what is wrong...

Related

C - properly importing stdcall functions from unmanaged DLL

I am trying to import a function from an unmanaged DLL into a C project by creating a .def file specifying the function I need to use. I am practicing on the WinAPI function MessageBoxA from user32.dll. It is an stdcall function, like the other WinAPI functions.
Here's how I create my .def file:
LIBRARY user32.dll
EXPORTS
_MessageBoxA#16
Then I create a .lib from it like this: lib /def:"C:\Path\to\def\user32.def" /
out:"C:\path\to\project\user32-mb.lib" which successfully creates user32-mb.lib and user32-mb.exp. Then, in my C project, I do the following:
#pragma comment(lib, "user32-mb.lib")
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
EXTERNC __declspec(dllexport) int __stdcall MessageBoxA(void *hWnd, char *lpText, char *lpCaption, int uType);
void main(){
MessageBoxA(0, "MessageBox test", "MessageBox test", 0x00000030L);
}
However, upon linking, it gives the following error:
error LNK2019: unresolved external symbol _MessageBoxA#16 referenced in function _main
However, when I change the declaration in the .def to this:
LIBRARY user32.dll
EXPORTS
MessageBoxA
And change the function prototype in my C code to cdecl instead of stdcall:
EXTERNC __declspec(dllexport) int __cdecl MessageBoxA(void *hWnd, char *lpText, char *lpCaption, int uType);
The message box actually appears, but right on closing, it throws an error:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
Which indicates that calling it with cdecl is also a bad idea since it requires stdcall after all.
The question is, what should I change in the .def file or in my project to avoid both errors and to import and call an stdcall function properly?
You need to change __declspec(dllexport) to __declspec(dllimport), as you are importing functions from a DLL, not exporting them:
EXTERNC __declspec(dllimport) int __stdcall MessageBoxA(void *hWnd, char *lpText, char *lpCaption, int uType);
^^
You need to use dllimport rather than dllexport, but in this case you should remove the __declspec(...) altogether.
And you need to specify the correct name for the function which is MessageBoxA.
LIBRARY USER32.dll
EXPORTS
MessageBoxA
Also it would be remiss of me not to point out that the correct main declaration is
int main(void)
I am still not entirely sure why, but removing the _ adding the ordinal to the function name my .def file fixed everything. My solution is:
LIBRARY USER32.dll
EXPORTS
MessageBoxA#16 #2093
Function definition:
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
typedef void *PVOID;
typedef PVOID HANDLE;
typedef HANDLE HWND;
typedef const char *LPCSTR;
typedef unsigned int UINT;
EXTERNC __declspec(dllimport)
int
__stdcall
MessageBoxA(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType);
This page indicates that winuser.h is the header. From there, you can see some macros are used, including WINUSERAPI and WINAPI. WINUSERAPI is conditionally #define-d at the beginning of that header. WINAPI can be found in the winbase.h header, where it can be seen to be tied to a calling convention, depending on the platform.
But a better question is: Why are you using dllexport and not dllimport?

C2059 syntax error using declspec macro for one function; compiles fine without it

I've making a shared library (cross-platform), but when trying to compile the Windows build I'm encountering the error:
secure_string.h(43) : error C2059: syntax error : 'type'
This is in regards to the SECURESTRING_API macro. It doesn't complain about the two usages in strlcpy and strlcat, but when trying to use it for 'str_from_last' it generates the above error.
If I remove it, it compiles fine, but the function then isn't exported from the DLL, making it quite useless!
A Google search has yielded no (relevant) results; has anyone encountered this before? I've tested on both Visual Studio 2008 and 2010, and the result is identical. The source file includes string.h and then this file - nothing else.
Header file:
#ifndef SECURE_STRING_H
#define SECURE_STRING_H
/* Provide MS Builds with import/export functionality
* BUILD_SECURE_STRING should be added to project preprocessor macros */
#if _WIN32
# if defined(BUILD_SECURE_STRING)
# define SECURESTRING_API __declspec(dllexport)
# else
# define SECURESTRING_API __declspec(dllimport)
# endif
#else
# define SECURESTRING_API
#endif
/* Windows on the whole, and glibc do not have/support strlc[at|py]
* This will almost certainly need revision for proper cross-platform checks */
#if _WIN32 || __GLIBC__ || !defined(HAVE_STRLCPY)
size_t SECURESTRING_API strlcat(char* dst, const char* src, size_t size);
size_t SECURESTRING_API strlcpy(char* dst, const char* src, size_t size);
#else
# define HAVE_STRLCPY 1
#endif
/* In case the active project has yet to include headers for 'BOOL' */
#ifndef BOOL
# define BOOL int
# define TRUE 1
# define FALSE 0
#endif
/*
| Locates 'search' within 'source', and if found, returns either the
| character itself, or the character after it if 'return_from_after_found'
| is TRUE.
| If it is not found, or any parameter is invalid, a NULL pointer is returned.
*/
char* SECURESTRING_API
str_from_last(char* source,
char search,
BOOL return_from_after_found);
#endif /* SECURE_STRING_H */
#if _WIN32
Are you sure you're entering this? I would:
#if defined(WIN32)
EDIT: That looks OK but this I think is it:
move the SECURESTRING_API before the return type (char*):
SECURESTRING_API char*
With this change your code compiles for me under VS2010 and MSDN confirms that is the required order:
The decl-specifier-seq should contain, among other things, a base type
(e.g. int, float, a typedef, or a class name), a storage class (e.g.
static, extern), or the __declspec extension. The init-declarator-list
should contain, among other things, the pointer part of
declarations.

problem in dll call in writing the calling process

I have following function defined in one dll:
__declspec( dllexport ) int __stdcall
mjscall(char *cmd, DWORD wtime, char *stdoutfile, char *stderrfile )
I need to write one process to call the above function.
I am doing it first time,I do not have much idea.
I have written the following code
#include <windows.h>
#include <windows.h>
#include <stdio.h>
#include <io.h>
#include <stdlib.h>
#include <limits.h>
extern __declspec( dllexport ) int __stdcall mjscall(char *cmd, DWORD wtime, char *stdoutfile, char *stderrfile );
typedef INT (*MJSCALL) (char *,DWORD, char *, char *);
int main()
{
char *a,*b,*c;
a=NULL;
b=NULL;
c=NULL;
DWORD aa =1;
int i;
HMODULE hLib;
MJSCALL ADD;
hLib=LoadLibrary("f3cucall.dll");
if(hLib==NULL)
{
return 1;
}
ADD=(MJSCALL)GetProcAddress(hLib,"mjscall");
if (ADD==NULL)
{
return 1;
}
(ADD)(a,aa,b,c);
return 0;
}
The "(ADD)(a,aa,b,c);" is causing the problem.
Can somebody help me out?
I think you mixed two things up:
the __declspec(dllexport) MSVC keyword exports functions from a DLL (tells the linker to do so), and the __declspec(dllimport) imports functions from a DLL. This is done at loading time, the linker will create all the necessary code to load the DLL and resolve the symbol. In fact, it adds some code to the exe to let the OS load the DLL. You can use functions declared with __declspec(dllimport) just like any normal internal function.
If you want to use this approach, you need the DLL's lib file, since it contains information for the linker to resolve the symbolic name. It doesn't actually contain code, only these information on the DLL for the linker. Additionally, you have to tell the linker that the function you want to use is located at a DLL, using the magic __declspec(dllimport) before the function declaration. That's why you provide a .lib and a header file (containing these declarations) with your DLL if you want to do it this way. You should rebuild the project that uses the DLL when you change the DLL, as the .lib file may have changed.
You can use the same header file in your DLL project and the projects that import from this DLL:
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
MYDLL_API void printMe(int);
The MyDLL_API get resolved to either __declspec(dllexport) (in the DLL project, where you define the MYDLL_EXPORTS in the project settings) or __declspec(dllimport) (in all projects that use the dll). This way, you only need one header file for the DLL.
Another method of calling DLL functions is to use LoadLibrary and GetProcAdress. These two are used to load a DLL at runtime. The main difference between loading a DLL at loading time and at runtime is that you have some control over loading the DLL at runtime, whereas the OS will do the job when the DLL is to load at loading time (e.g. show a message box if the DLL cannot be found and do not run the process).

Global variable in a different library, C

I am trying a global variable to hold my error message in C.
One library called Utils has:
#ifndef private_error_h
#define private_error_h
extern char error[1024];
__declspec(dllexport) void FillError(char* newError);
#define GetErr() error
#endif
File error.c:
#include "private_error.h"
char error[1024];
void FillError(char* newError) {
// ...
}
Then I try to use it in a program:
#include "private_error.h"
int main() {
FillError("General error");
printf("%s\n", GetErr());
return 0;
}
It creates two variables with different addresses. How can I make the program use the variable from the Utils library?
I did manage to bypass this problem by changing GetErr to a function returning the string, but I am still wondering where the error is here.
You have to declare it in your header file as
extern char error[];
and in your code file (.c file) , declare it
char error[1024];
You are allocating it twice
Why not use function like this:
in .h:
char* GetErr();
and in .cpp:
char* GetErr() { return error; }
Try to avoid global variables. In file scope its pretty safe, but if you try to use it trough many files it can cause big errors.

DLL function not exported: Unable to find an entry point named TestFunc

I'm busy getting to know a tiny bit of C/C++, and interop with C#. I've checked several examples of creating a simple Win32 DLL and using this from C#, but when I try and call into my DLL, I get the runtime error: "Unable to find an entry point named TestFunc". My DLL looks like this, and I created it from a Win32 DLL project, with the empty project option:
Header:
__declspec(dllexport) int TestFunc(char *, char *, char *);
Code file:
#include "stdafx.h"
#include "TestLib.h"
__declspec(dllexport) int TestFunc(char *arg1, char *arg2, char *arg3)
{
char str1[] = "Brady Kelly";
char str2[] = "Hello World";
char str3[] = "1234567890";
strcpy(arg1, str1);
return 128;
}
What am I doing wrong?
Is your function compiled using C or C++ bindings? You don't specify, but it looks to me like there is a possibility that you are using the C++ compiler - the compiler uses very different name mangling from the C compiler and you will not be able to find the name "TestFunc" as simply as if you were using the C compiler or using C name mangling rules.
To simply tell the C++ compiler to use C name mangling rules, use this in the header file:
extern "C"
{
__declspec(dllexport) int TestFunc(char *, char *, char *);
}
Also, you only need the declspec in front of the function declaration (in the header file), not the definition. A useful tool for examining what is exported from the DLL, and what the DLL depends on is Dependency Walker.
Actually since you have tagged this question as C, I'd suggest a minor change from what 1800 INFORMATION's solution:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef EXPORT_MODE
#define METHODTYPE __declspec(dllexport)
#else
#define METHODTYPE __declspec(dllimport)
#endif
#ifdef __cplusplus
}
#endif
/*! _The_ method */
METHODTYPE int TestFunc(char *, char *, char *);
This will let you use the same header both in clients' code and your code.
NB: Dependency Walker is no longer bundled with VS2008. You must download it if you are using VS2008.

Resources