读书人

string amp; 作为 C++ dll 接口函数的参数

发布时间: 2013-10-14 12:54:46 作者: rapoo

string & 作为 C++ dll 接口函数的参数问题
dll中(Win32的):
int func(string &x)
{
x = "11111111111111111111111111111111111111111111111111";
}

exe中(可能是MFC程序):
void main()
{
string x = "";
func(x);
}

程序结束时崩溃,有没有方法解决,在不改变接口的前提下。

目前知道原因,但现在不能改接口,32为机器上没问题的,64位机器上就不行,x的长度小于16时没问题,长了就不行。

我知道这里有高手的,我服了,求赐教。




string c++ 64位 win32 接口参数
[解决办法]
接口 c 化, 不要用 c++ 的类
[解决办法]
那就使用跟对方相同版本的 vc
要求对方提供 debug 版, release 版
的 for x86, x64 的 lib 库
和可执行文件.

[解决办法]

引用:
那就使用跟对方相同版本的 vc
要求对方提供 debug 版, release 版
的 for x86, x64 的 lib 库
和可执行文件.


引用:
接口 c 化, 不要用 c++ 的类


择其一而行之;
[解决办法]
摒弃string
使用char s[MAXLEN]并将s[MAXLEN]放在一个共享数据段中。
Using Shared Memory in a Dynamic-Link Library
This section shows how the DLL entry-point function can use a file-mapping object to set up memory that can be shared by processes that load the DLL. The shared DLL memory persists only as long as the DLL is loaded.

The example uses file mapping to map a block of named shared memory into the virtual address space of each process that loads the DLL. To do this, the entry-point function must:

Call the CreateFileMapping function to get a handle to a file-mapping object. The first process that loads the DLL creates the file-mapping object. Subsequent processes open a handle to the existing object. For more information, see Creating a File-Mapping Object.
Call the MapViewOfFile function to map a view into the virtual address space. This enables the process to access the shared memory. For more information, see Creating a File View.
// File: DLLSHMEM.C.
// The DLL entry-point function sets up shared memory using
// a named file-mapping object.

#include <windows.h>
#include <memory.h>

#define SHMEMSIZE 4096

static LPVOID lpvMem = NULL; // pointer to shared memory

BOOL DllMain(HINSTANCE hinstDLL, // DLL module handle
DWORD fdwReason, // reason called
LPVOID lpvReserved) // reserved
{
HANDLE hMapObject = NULL; // handle to file mapping
BOOL fInit, fIgnore;

switch (fdwReason)
{
// The DLL is loading due to process
// initialization or a call to LoadLibrary.

case DLL_PROCESS_ATTACH:

// Create a named file mapping object.

hMapObject = CreateFileMapping(
(HANDLE) 0xFFFFFFFF, // use paging file
NULL, // no security attributes


PAGE_READWRITE, // read/write access
0, // size: high 32-bits
SHMEMSIZE, // size: low 32-bits
"dllmemfilemap"); // name of map object
if (hMapObject == NULL)
return FALSE;

// The first process to attach initializes memory.

fInit = (GetLastError() != ERROR_ALREADY_EXISTS);

// Get a pointer to the file-mapped shared memory.

lpvMem = MapViewOfFile(
hMapObject, // object to map view of
FILE_MAP_WRITE, // read/write access
0, // high offset: map from
0, // low offset: beginning
0); // default: map entire file
if (lpvMem == NULL)
return FALSE;

// Initialize memory if this is the first process.

if (fInit)
memset(lpvMem, '\0', SHMEMSIZE);

break;

// The attached process creates a new thread.

case DLL_THREAD_ATTACH:
break;

// The thread of the attached process terminates.

case DLL_THREAD_DETACH:
break;

// The DLL is unloading from a process due to
// process termination or a call to FreeLibrary.

case DLL_PROCESS_DETACH:

// Unmap shared memory from the process's address space.

fIgnore = UnmapViewOfFile(lpvMem);

// Close the process's handle to the file-mapping object.

fIgnore = CloseHandle(hMapObject);

break;

default:
break;
}

return TRUE;
UNREFERENCED_PARAMETER(hinstDLL);
UNREFERENCED_PARAMETER(lpvReserved);
}

// SetSharedMem sets the contents of shared memory.

VOID SetSharedMem(LPTSTR lpszBuf)
{
LPTSTR lpszTmp;



// Get the address of the shared memory block.

lpszTmp = (LPTSTR) lpvMem;

// Copy the null-terminated string into shared memory.

while (*lpszBuf)
*lpszTmp++ = *lpszBuf++;
*lpszTmp = '\0';
}

// GetSharedMem gets the contents of shared memory.

VOID GetSharedMem(LPTSTR lpszBuf, DWORD cchSize)
{
LPTSTR lpszTmp;

// Get the address of the shared memory block.

lpszTmp = (LPTSTR) lpvMem;

// Copy from shared memory into the caller's buffer.

while (*lpszTmp && --cchSize)
*lpszBuf++ = *lpszTmp++;
*lpszBuf = '\0';
}

Note that the shared memory can be mapped to a different address in each process. For this reason, each process has its own instance of the lpvMem parameter, which is declared as a global variable so that it is available to all DLL functions. The example assumes that the DLL global data is not shared, so each process that loads the DLL has its own instance of lpvMem.

In this example, the shared memory is released when the last handle to the file-mapping object is closed. To create persistent shared memory, a DLL can create a detached process (see CreateProcess) when the DLL is first loaded. If this detached process uses the DLL and does not terminate, it has a handle to the file-mapping object that prevents the shared memory from being released.



[解决办法]



如果对方使用了静态链接运行库,那就准备哭吧。无解

[解决办法]
传引用DLL里肯定会动态分配,然后exe里析构释放内存,如果是静态链接CRT应该是没办法的,因为静态链接CRT,DLL和exe用的不是同一个堆,一个堆里分配另一个堆释放,崩溃妥妥的。
[解决办法]
珍惜生命,扔了这个dll吧。
只能使用纯C接口的标准dll
[解决办法]
string & 作为 C++ dll 接口函数的参数有关问题学习一下

[解决办法]
再写一个dll,尝试对现有的dll进行封装,导出一个接口为纯C的函数,此函数实现纯C字符串到string的转换。
[解决办法]
还有,我觉得你的测试程序蛮有问题的……

通常这种引用方式传进去的string,居然还在DLL对它进行写操作??
[解决办法]
在外面先把内存resize好吧,这破接口写的。
[解决办法]
有可能就是版本不一致的问题。
我这里测了没问题
可能是string模板旧版本的dll里的实现和你用的编译器当前的实现不一样。而编译时编译器只按类型名识别编译,所以编译也就通过了。。

[解决办法]
另外func和main里面string使用的却是各自的分配器实现


[解决办法]



叫你写一个dll包装一下的,解决不了根本问题。如果dll使用了静态库,而且你传入了空string对象,100%崩溃,建议dll使用共享dll方式重新编译,且你的exe也使用使用共享dll方式重新编译,这样就不会有问题了。

如果不让重新编译dll,你就照前面哥们说的办法给string对象分配好空间再调用dll导出函数吧,在这样的情况下,这是唯一的办法。
[解决办法]


另外,写dll的哥们,俺目测一下他的经验多半只有1、2年。
string & 作为 C++ dll 接口函数的参数有关问题
[解决办法]


俺还是不说话了吧。string & 作为 C++ dll 接口函数的参数有关问题
[解决办法]
一直以为楼主是个带把的爷们,没想到居然是个MM。。。这头像太有欺骗性了
[解决办法]


快,头像换得真快,为什么结帖没这么快呢。
string & 作为 C++ dll 接口函数的参数有关问题

读书人网 >C++

热点推荐