回梦

文章 评论 浏览 30

回梦 2025-02-20 19:28:49

尝试一下。将Excel Workbook放入SharePoint之后,请从SharePoint内部打开工作簿,然后选择编辑下拉列表, 在桌面应用程序中打开

“在此处输入图像说明”

然后,在工作簿中,单击 file > info > 复制路径。 (这将为您提供电源查询所需的路径才能直接检索工作簿。如果您尝试使用SharePoint的功能复制路径的路径,这与您所获得的路径不同。)

“在此处输入图像说明”

“在此处输入图像说明”

粘贴该路径以安全地使用。然后关闭您的工作簿并打开电源查询。

在电源查询中,创建两个新参数:

单击 home > 管理参数的底部按钮> 新参数

”在此处输入图像描述

将名称从 parameter1 更改为路径并将类型更改为 text ,然后将您复制的工作簿复制的路径粘贴到当前值 box 。然后,从刚粘贴的路径中删除了最后一个前向斜线(/)之后的所有文本。确保您做< / strong>将最后 /包含在路径中。您将在单独的参数中放置以下内容的文件名,并且不需要?web = 1 < / em>。

不要单击确定。,请单击 new ,在管理参数窗口的顶部。这将设置您创建文件名参数。

将名称从 parameter1 更改为 fileName ,然后将 type 更改为 text ,然后粘贴您复制的文件名工作簿进入当前值框。同样,您不需要原始路径中的?web = 1

单击确定。

现在,您可以在源行中使用参数,路径和文件名。这是这样做的方法:

Source = Excel.Workbook(Web.Contents(path & filename), null, true)

这将为您提供这样的表:

”在此处输入图像描述”

------------------------------------------------------------------------ -

对于Mirza的后续操作,关于从SharePoint文件夹中提取文件,请尝试以下操作:

  1. 获取数据,选择SharePoint文件夹连接器,然后单击
    连接。
  2. 对于SharePoint文件夹站点URL,输入您的URL
    您的 root 在SharePoint中使用文件夹,然后单击“确定”。
  3. 您可能必须输入您的凭据。如果是这样,请这样做。
  4. 此时,您应该看到SharePoint中文件的列表。单击转换数据按钮。
  5. 在您接下来看到的表中:
    • 将名称列过滤到的名称,只有一个您的文件
      想打开。 (使用顶端的下拉箭头。)
    • 将文件夹路径列过滤到仅一个路径。 (同样命名
      文件可以存储在多个文件夹中,您需要确保
      您正在通过与正确的文件匹配正确的文件
      文件夹,这为此设定了阶段。)
  6. 文件夹,这为此设定了 但这一次:
    • 对于路径的当前值,请从您当前在表格的文件夹路径列中粘贴值;和
    • 对于文件名的当前值,请从您当前的表的名称列粘贴值。
  7. 然后,在“过滤行”的“公式”框中,将文件名(包括报价)更改为文件名,然后更改路径的名称(包括引号)到路径。

您应该以这样的代码结束(yourdomain.sharepoint.com/your/root/folder/url将是您的 root root 在SharePoint中的文件夹):

let
    Source = SharePoint.Files("https://yourdomain.sharepoint.com/your/root/folder/URL", [ApiVersion = 15]),
    #"Filtered Rows" = Table.SelectRows(Source, each (([Name] = filename and [Folder Path] = path)))
in
    #"Filtered Rows"

您应该看到类似的东西此:

“在此处输入图像说明”

在内容列中单击二进制文件。

------------------------------------------------------------------------ -

对于Mirza的第二次随访,关于从SharePoint文件夹中摘取多个文件而不是仅一个文件,请尝试以下操作:

  1. 在获取数据中,选择SharePoint文件夹连接器,然后单击
    连接。
  2. 对于SharePoint文件夹站点URL,输入您的URL
    在SharePoint中使用文件的root文件夹,然后单击“确定”。你可能有
    输入您的凭据。如果是这样,请这样做。
  3. 此时,您应该看到SharePoint中文件的列表。单击转换数据按钮。

  1. 您在表中看到的下一个:将文件夹路径列滤除到仅一个路径 -您想要的文件所在的文件夹的路径。 (请注意,这与我以前的答案中解决的单个文件不同,因为此文件通过名称列跳过过滤。)

”输入图像描述在这里“

”在此处输入图像描述”

  1. 接下来,设置一个称为路径的参数。对于路径的当前值,请从您当前使用的表路径列复制并粘贴值。
  • 要从文件夹路径列复制路径:

”图像描述在此处“

  • 粘贴您刚刚从文件夹路径列复制到的路径
    路径参数的当前值:

    单击“家”,然后单击“管理参数”,然后,如果您尚未创建路径参数,请单击新(否则单击路径参数以选择它):

单击“ .sstatic.net/vggHt.png" rel="nofollow noreferrer">“在此处输入图像说明”

确保您的路径参数如下:

“在此处输入图像描述”

  1. 然后,在过滤行的公式框中,更改
    路径(包括引号)到路径。也就是说,更改此信息:

    = table.selectrows(源,每个([folder path] =“ https://yourdomain.sharepoint.com/sites/testteam/shared documents /shared documents/enter/general/”))

    to ...

    = table.selectrows(源,每个(([folder path] = path)))

您应该能够用任何其他有效根文件夹中的文件夹路径。

由于这些源文件位于SharePoint内,因此SharePoint的访问控件占上风。因此,要使用户能够访问实际的源文件,这是刷新需要做的,需要刷新的用户将需要适当的SharePoint访问权限的源文件以访问它们。但是,我可以肯定的是,一旦完成了刷新,任何可以访问您的文件的用户(无论是在Excel还是Power BI文件中)都应该能够看到其结果,而没有他们的结果需要对基础源文件的SharePoint访问权限。我的理解是,只有那些实际访问源文件(例如刷新)的人才需要访问这些文件的人。无论如何,这是我的经验。

Try this. After you have placed your excel workbook into SharePoint, open the workbook from within SharePoint and then select the Editing dropdown and Open in Desktop App:

enter image description here

Then, in the workbook, click File > Info > Copy Path. (This will get you the path you need for power query to directly retrieve the workbook. It is different than what you would have gotten if you tried to copy the path using SharePoint's features for copying the path.)

enter image description here

enter image description here

Paste that path somewhere safe for reuse. Then close your workbook and open Power Query.

In Power Query, create two new parameters:

Click Home > the bottom part of the Manage Parameters button > New Parameters:

enter image description here

Change the name from Parameter1 to path and change the Type to Text, then paste the path you copied for your workbook into the Current Value box. Then, from the path you just pasted, delete all the text that follows the last forward slash (/). Make sure you do include that last / in the path. You'll put the file name that follows the / in a separate parameter and won't need the ?web=1.

enter image description here

Don't click OK. Instead, click New, at the top of the Manage Parameters window. This will set you up to create the filename parameter.

Change the name from Parameter1 to filename and change the Type to Text, then paste the filename you copied for your workbook into the Current Value box. Again, you won't need the ?web=1 from the original path.

enter image description here

Click OK.

Now you can use the parameters, path and filename in your source line. And here's how to do that:

Source = Excel.Workbook(Web.Contents(path & filename), null, true)

This will give you a table like this:

enter image description here

-------------------------------------------------

For Mirza's follow-up, regarding pulling the files from the SharePoint folder, try this instead:

  1. In Get Data, select the SharePoint Folder connector and click
    Connect.
  2. For the SharePoint Folder Site URL, enter your URL for
    your root folder for your files in SharePoint and click OK.
  3. You may have to enter your credentials. If so, do that.
  4. At this point, you should see a listing of your files that you have in SharePoint. Click the Transform Data button.
  5. In the table that you see next:
    • Filter the Name column to the name of only one file that you
      want to open. (Use the dropdown arrow at the top-right.)
    • Filter the Folder Path column to only one path. (Same named
      files can be stored in multiple folders and you'll want to be sure
      you are selecting the right file by matching it with its correct
      folder, and this sets the stage for that.)
  6. Next, set up the two parameters--path and filename--similarly to what I said in my first approach. But this time:
    • For the path's current value, paste the value from the Folder Path column of the table you're currently in; and
    • For the filename's current value, paste the value from the Name column of the table you're currently in.
  7. Then, in the formula box for the Filtered Rows, change the name of the file (including the quotes) to filename and change the name of the path (including the quotes) to path.

You should wind up with code like this (yourdomain.sharepoint.com/your/root/folder/URL would be your URL to your root folder for your documents in sharepoint instead):

let
    Source = SharePoint.Files("https://yourdomain.sharepoint.com/your/root/folder/URL", [ApiVersion = 15]),
    #"Filtered Rows" = Table.SelectRows(Source, each (([Name] = filename and [Folder Path] = path)))
in
    #"Filtered Rows"

You should see something like this:

enter image description here

Click Binary, in the Content column.

-------------------------------------------------

For Mirza's second follow-up, regarding pulling multiple files from the SharePoint folder instead of just one file, try this instead:

  1. In Get Data, select the SharePoint Folder connector and click
    Connect.
  2. For the SharePoint Folder Site URL, enter your URL for your
    root folder for your files in SharePoint and click OK. You may have
    to enter your credentials. If so, do that.
  3. At this point, you should see a listing of your files that you have in SharePoint. Click the Transform Data button.

enter image description here

  1. In the table that you see next: Filter the Folder Path column to only one path--the path of the folder where the files you want are located. (Note that this is different from looking for a single file, addressed in my previous answers, because this skips filtering by the Name column.)

enter image description here

enter image description here

  1. Next, set up a parameter called path. For the path's current value, copy and paste the value from the Folder Path column of the table that you're currently in.
  • To copy the path from the Folder Path column:

enter image description here

  • To paste the path you just copied from the Folder Path column to the
    path parameter's current value:

    Click Home, then click on Manage Parameters, then if you haven't already created the path parameter, click new (otherwise click on the path parameter to select it):

enter image description here

Make sure your path parameter is set up like this:

enter image description here

  1. Then, in the formula box for the Filtered Rows, change the name of
    the path (including the quotes) to path. That is, change this:

    = Table.SelectRows(Source, each ([Folder Path] = "https://yourdomain.sharepoint.com/sites/TestTeam/Shared Documents/General/"))

    to...

    = Table.SelectRows(Source, each (([Folder Path] = path)))

You should be able to replace the current value of the path parameter with any other valid folder path within your root folder.

Since these source files reside within SharePoint, SharePoint's access controls prevail. So, for a user to be able to access the actual source files, which is what a refresh needs to do, the users who need to refresh will need appropriate SharePoint access rights to the source files in order to access them. However, I'm fairly certain that once the refresh has been done, any users who have access to your file that is built from this query's results (be it in an excel or Power BI file) should be able to see its results without them needing SharePoint access rights to the underlying source files. My understanding is that only those people who actually access to the source files, like for refresh, require the SharePoint access to those files. This has been my experience anyway.

如何为来自SharePoint的文件创建动态文件路径,以查询power查询?

回梦 2025-02-20 11:46:33

我不确定它是否仍然相关,但是您需要ACE字符串“ WP”。这允许相关的身份(在SID字符串中提到)开始/停止服务。因此,如果您想让管理员停止和启动的能力,则需要使用以下内容(“ BA” SID字符串代表内置管理员,也可以添加管理员帐户的SID)

D:(A;;CCLCSWRPLOCRRCWDWP;;;BA)

:您写道:

D:P(A;;CCLCSWRPLOCRRCWD;;;SY)(A;;CCLCSWLOCRRCWD;;;SU)(A;;CCLCSWRPLOCRRCWDWP;;;BA)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

I am not sure if it is still relevant, but you need the ACE string "WP". This allows the relevant identity (mentioned in the SID string) to start/stop the service. So if you want to let admins the ability to stop and start, you need to use the following (the "BA" SID string stands for Built-in administrators, you can also add the SID of the administrator account):

D:(A;;CCLCSWRPLOCRRCWDWP;;;BA)

In context of what you wrote:

D:P(A;;CCLCSWRPLOCRRCWD;;;SY)(A;;CCLCSWLOCRRCWD;;;SU)(A;;CCLCSWRPLOCRRCWDWP;;;BA)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

我们为Windows服务编写了服务描述符,在该服务中,用户没有特权开始/停止服务,但管理员可以启动/停止服务

回梦 2025-02-20 00:25:39

似乎您还没有诚实地尝试。来自文档它是在顶部写的:

// Obtain shared preferences.
final prefs = await SharedPreferences.getInstance();

// Save an String value to 'action' key.
await prefs.setString('action', 'Start');

// Try reading data from the 'action' key. If it doesn't exist, returns null.
final String? action = prefs.getString('action');

It seems like you haven't given in an honest try yet. From the documentation it is written at the top:

// Obtain shared preferences.
final prefs = await SharedPreferences.getInstance();

// Save an String value to 'action' key.
await prefs.setString('action', 'Start');

// Try reading data from the 'action' key. If it doesn't exist, returns null.
final String? action = prefs.getString('action');

使用带有共享首选项的字符串数据

回梦 2025-02-19 20:07:51

我不明白的一件事是,您正在使用vlookup(...,...,1,...):据我了解vlookup()用于以下情况:

a    b    c
1   10  100
2   20  200
3   30  300

...您想在'c'列中找到值,与“ a”列中的值2相对应。在这种情况下,您正在寻找值2,并且在第三列中查看,例如vlookup(...,...,3,...)

但是,如果您只是在寻找该值本身,而不是使用vlookup(lookup_value,range,1,extcret_match),您可以使用match> match(lookup_value,range,range,extcret_match)。

One thing I don't understand, is the fact that you are using VLookup(...,...,1,...): as far as I understand VLookup() is used for following case:

a    b    c
1   10  100
2   20  200
3   30  300

... and you want to find the value in the 'c' column, corresponding with value 2 in column 'a'. In that case you are looking for value 2 and you look in the third column, something like VLookup(...,...,3,...).

However, if you're just looking for that value itself, instead of using VLookup(lookup_value,range,1,exact_match), you can use Match(lookup_value,range,exact_match).

vlookup不显示任何东西

回梦 2025-02-18 22:44:33

下班后,这是完全没有证件的解决方案。

三个(或两个)1x图像:

  • 应为400.240(实际上,如果大小错了,就不会引起任何问题)

三个(或两个)2x图像:

  • 必须严格严格为800.480 ,或者会遇到灾难性的失败。在4K型号上

“

令人沮丧的是,资产文件夹中的某些图像包括工作和正确的警报,例如:

“

但是,实际的“应用程序图标”插槽没有任何工作警报。

底线,必须正好是800.480。


“顶架”图像是:

1920.720和3840.1440

“顶架宽”图像是:

2320.720和4640.1440

After hours, here's the solution which is totally undocumented.

The three (or two) 1x images:

  • Should be 400.240 (in fact, causes no problems if size is wrong)

The three (or two) 2x images:

  • MUST be strictly 800.480 or will fail catastrophically and silently on 4K models

xcode

Depressingly, SOME of the images in the asset folder, include working and correct alerts, for example:

alert

However the actual "App Icon" slots DO NOT HAVE any working alerts.

Bottom line, MUST be exactly 800.480.


The "Top Shelf" images are:

1920.720 and 3840.1440

The "Top Shelf Wide" images are:

2320.720 and 4640.1440

AppleTV图标的奇怪问题 - 在4K型号上选择时图标会收缩?

回梦 2025-02-18 21:56:39

您的应用程序是业务类型吗?第三点提到“创建一个元应用:转到开发人员。Facebook.com&gt;我的应用程序&gt;创建应用程序。选择“业务”类型,然后在屏幕上关注提示”。

Is your app a business type? The third point mentions "Create a Meta App: Go to developers.facebook.com > My Apps > Create App. Select the "Business" type and follow the prompts on your screen"

Facebook应用程序 - 将产品添加到我的应用程序时没有Wha​​tsApp

回梦 2025-02-18 13:56:56

(我简要查看C程序的构建块,然后检查通常隐藏在GCC调用后面的构建步骤。)

传统的编译语言,例如C和C ++,在通常是源文件中组织了一个一个一个,“编译”到一个“对象文件”中。每个源文件都是一个“翻译单元” - 在处理了所有包含指令之后。 (因此,翻译单元通常由一个以上的文件组成,相同的包含文件通常发生在一个以上的翻译单元中 - 文件和翻译单元严格说是N:M关系。但是,务实地可以说一个人可以说一个“翻译单元”是一个c文件。)

要将单个源文件编译到对象文件中,一个人将-c flag传递给编译器:

gcc -c myfile.c

这将在同一目录中创建myfile.o,或者也许myfile.obj

对象文件包含机器代码和数据(以及潜在的调试信息,但我们在这里忽略了它)。机器代码包含函数,数据以变量的形式出现。对象文件中的函数和变量都具有称为“符号”的名称。编译器通常通过准备下划线或类似程序,在C ++中转换程序中的变量和函数名称,生成的(“ mangled”)名称包含有关类型和函数的信息。

某些符号,例如全局变量和正常函数的名称,可从其他对象文件中使用;他们被“出口”。

只需简化的符号就可以将其视为地址别名:对于功能,该名称是跳跃目标地址的别名;对于变量,名称是程序可以读取的内存位置的地址和可以编写的记忆位置的一个别名。

您的文件帮助。C包含函数herp的代码。 C中的功能默认情况下具有“外部链接”,可以从其他翻译单元中使用它们。他们的名字 - “符号” - 被导出。

在Modern C中,源文件使用 在不同的翻译单元中定义的名称必须声明该名称。这告诉编译器如何处理它,以及在源代码中可以在哪种方式上使用句法(例如,调用函数,分配到变量,索引一个数组)。编译器会产生从此“符号地址”中读取的代码,或跳到该“符号地址”;链接器的作业是将所有这些符号地址替换为“真实”内存位置,这些位置指向最终可执行文件中的现有数据和代码,以便跳跃和内存访问已降落在所需的位置。

文件中的名称(函数,变量)的声明是使用的声明,它可以是“手动”,例如void herp();,在您的文件中直接出现在您的文件中首先使用。不过,更通常,在翻译单元中定义的名称可以使用其他翻译单元,在标题文件中声明了您的helper.h。使用翻译单元使用#include -ing it在标题文件中使用的“罐头”声明。这里没有魔术。一个包含指令只需插入包含的文件文本,就好像它直接写在文件中一样。差异恰好为零。特别是,包括标头文件不会告诉链接器与相应的源文件链接。原因很简单:链接器永远不会知道随附的文件,因为在编译过程中删除了该知识进入对象文件。

这意味着在您的情况下,必须汇总help.c,并且必须告诉链接器与程序的其余部分结合(“链接”),在您的情况下,汇编中的代码main.c

讨论如何完成工作更加困难,因为此过程非常普遍,以至于典型的C编译器集成了编译和链接阶段:gcc -o myprog help.c main.c main.c main.c main.c简单地做所有必要的事情创建一个可执行的myProg

当我们说“编译器”时,例如参考gcc,我们通常是指从命令行中获取命令和文件的“编译器驱动程序”,并执行必要的步骤以实现所需的结果,例如从我们的来源生产可执行程序。 GCC的实际编译器是cc1,它会生成一个必须将 as “组装”到对象文件中的汇编文件。编译源文件后,GCC使用适当的选项调用链接器,从而产生可执行文件。

这是一个示例会话详细介绍阶段:

$ ls
Makefile  help.c  help.h  main.c

$ /lib/gcc/x86_64-pc-cygwin/7.4.0/cc1 main.c
 main
Analyzing compilation unit
Performing interprocedural optimizations
 <*free_lang_data> <visibility> <build_ssa_passes> <opt_local_passes> <targetclone> <free-inline-summary> <emutls> <whole-program> <inline>Assembling functions:
 <materialize-all-clones> <simdclone> main
Execution times (seconds)
 phase setup             :   0.00 ( 0%) usr   0.00 ( 0%) sys   0.00 (22%) wall    1184 kB (86%) ggc
 TOTAL                 :   0.00             0.00             0.01               1374 kB

$ ls
Makefile  help.c  help.h  main.c  main.s

$ /lib/gcc/x86_64-pc-cygwin/7.4.0/cc1 help.c
 herp
Analyzing compilation unit
Performing interprocedural optimizations
 <*free_lang_data> <visibility> <build_ssa_passes> <opt_local_passes> <targetclone> <free-inline-summary> <emutls> <whole-program> <inline>Assembling functions:
 <materialize-all-clones> <simdclone> herp
Execution times (seconds)
 phase setup             :   0.01 (100%) usr   0.00 ( 0%) sys   0.00 (33%) wall    1184 kB (86%) ggc
 TOTAL                 :   0.01             0.00             0.01               1370 kB

$ ls
Makefile  help.c  help.h  help.s  main.c  main.s

我们现在有两个汇编文件,main.s and help.s,可以将它们与汇编程序一起组装到对象文件中。但是,让我们快速查看help.s

$ cat help.s

        .file   "help.c"
        .text
        .globl  some_variable
        .data
        .align 4
some_variable:
        .long   1
        .text
        .globl  herp
        .def    herp;   .scl    2;      .type   32;     .endef
        .seh_proc       herp
herp:
        pushq   %rbp
        .seh_pushreg    %rbp
        movq    %rsp, %rbp
        .seh_setframe   %rbp, 0
        .seh_endprologue
        nop
        popq    %rbp
        ret
        .seh_endproc
        .ident  "GCC: (GNU) 7.4.0"

即使我们对汇编器一无所知,我们也可以清楚地识别符号some_variableherp,是组装标签。

忘记了我添加了一个可变定义以帮助

$ cat help.c

#include "help.h"
int some_variable = 1;
void herp() {}

$ as main.s -o main.o

$ ls
Makefile  help.c  help.h  help.s  main.c  main.o  main.s

$ as help.s -o help.o

$ ls
Makefile  help.c  help.h  help.o  help.s  main.c  main.o  main.s

啊,是的,我 我们可以看到哪些符号被导出(“ extern”)或所需的(“未定义”),该实用程序 nm (“ n ame m 钓鱼”):

$ nm --extern-only help.o

0000000000000000 T herp
0000000000000000 D some_variable

$ nm --extern-only main.o
                 U __main
                 U herp

“ t”表示符号在“文本”部分中,其中包含代码; “ D”是数据部分,“ U”代表“未定义”。 (未定义的__ main gcc和/或cygwin quirk 。)

在这里您有问题的源头:除非您将main.o与定义的对象文件配对未定义的符号,链接器无法“解析”名称并不能产生跳跃。没有跳跃目的地。

现在,我们可以将两个对象文件链接到可执行文件。 cygwin要求我们与cygwin.dll链接;对不起。

$ ld main.o help.o /bin/cygwin1.dll -o main

$ ls
Makefile  help.c  help.h  help.o  help.s  main*  main.c  main.o  main.s

就是这样。我应该补充说,该程序无法正常运行。它没有结束,也不会对CTRL-C反应;我可能缺少一些GNU或Windows建立了GCC为我们做的错综复杂。

啊,makefiles。 makefiles由这些目标的 target 定义和依赖关系:一行

main:help.o main.o

指定目标“ main”两个.o文件。
MakeFiles通常还包含规则指定如何产生目标。但是制造有内置的规则;它知道您调用编译器从.c文件中生成.o文件(并且它会自动考虑此依赖关系),并且知道您将O文件链接在一起以根据目标链接到目标,前提是目标与.o文件之一相同。

因此,我们不需要任何规则:我们简单地定义了非依赖依赖性。您项目的整个makefile归结为:

$ cat Makefile

CC=gcc
main: help.o main.o
help.o: help.h
main.o: help.h

cc = gcc指定要使用的C编译器。 CC是指定C编译器的内置变量(CXX将指定C ++编译器,例如G ++)。

让我们看看:

$ make

gcc    -c -o main.o main.c
gcc    -c -o help.o help.c
gcc   main.o help.o   -o main
$ ls
Makefile  help.c  help.h  help.o  main.c  main.exe*  main.o

依赖关系有效吗?

$ make
make: 'main' is up to date.

$ touch main.c

$ make
gcc    -c -o main.o main.c
gcc   main.o help.o   -o main

$ touch help.h

$ make
gcc    -c -o main.o main.c
gcc    -c -o help.o help.c
gcc   main.o help.o   -o main

看起来不错:触摸单个源文件后,只需编译该文件;但是,触摸两个文件依赖的标头使得两者都使得两者兼而有之。无论如何,链接都需要完成。

(I briefly look at the building blocks of C programs and then examine the build steps normally hidden behind gcc calls.)

Traditional compiled languages, for example C and C++, are organized in source files which normally are, one by one, "compiled" into one "object file" each. Each source file is one "translation unit" — after all the include directives have been processed. (Therefore, a translation unit typically consists of more than one file, and the same include file typically occurs in more than one translation unit — files and translation units have, strictly spoken, an n:m relation. But pragmatically one can say that a "translation unit" is a C file.)

To compile a single source file into an object file, one passes the -c flag to the compiler:

gcc -c myfile.c

This creates myfile.o, or perhaps myfile.obj, in the same directory.

Object files contain machine code and data (and potentially debug information, but we ignore that here). The machine code contains functions, and the data comes in the shape of variables. Both functions and variables in the object files have names which are called "symbols". The compiler typically transforms the variable and function names in the program by prepending an underscore or the like, and in C++ the generated ("mangled") name contains information about the type and, for functions, parameters.

Some symbols, for example the names of global variables and normal functions, are usable from other object files; they are "exported".

A symbol can, with only slight simplification, be thought of as an address alias: For a function, the name is an alias for the target address of a jump; for variables, the name is an alias for the address of a memory location from which the program can read and to which it can write.

Your file help.c contains the code for the function herp. Functions in C have by default "external linkage", they can be used from other translation units. Their name — the "symbol" — is exported.

In modern C, a source file using a name defined in a different translation unit must declare the name. This tells the compiler what to do with it, and in which ways it can syntactically be used in the source code (e.g., call a function, assign to a variable, index an array). The compiler produces code that reads from this "symbolic address" or jumps to that "symbolic address"; it is the linker's job to replace all those symbolic addresses with "real" memory locations that point to existing data and code in the final executable, so that the jumps and memory accesses are landing at the desired locations.

The declaration of a name (function, variable) in the file that's using it can be "manual", like void herp();, appearing directly in your file before the first use. More typically though, the names defined in a translation unit that other translation units can use are declared in a header file, your helper.h. The using translation unit uses the "canned" declarations in the header file by #include-ing it. There is no magic here; an include directive simply inserts the include file text as if it were written in the file directly. There is exactly zero difference. In particular, including a header file does not tell the linker to link with the corresponding source file. The reason is simple: The linker never knows about the included file because that piece of knowledge is erased during the compilation into an object file.

This means in your case that help.c must be compiled, and that the linker must be told to combine ("link") it with the rest of the program, in your case the code from the compilation of main.c.

The discussion how that is done is a bit more difficult because this procedure is so common that the typical C compiler integrates compilation and link stage: gcc -o myprog help.c main.c simply does everything necessary to create an executable myprog.

When we say "compiler", e.g. referring to gcc, we normally actually mean the "compiler driver" which takes the commands and files from the command line and performs the necessary steps to achieve the desired results, like producing an executable program from our sources. The actual compiler for gcc is cc1 which produces an assembly file which must be "assembled" with as into an object file. After the source files are compiled, gcc calls the linker with the appropriate options, which produces the executable.

Here is a sample session detailing the stages:

$ ls
Makefile  help.c  help.h  main.c

$ /lib/gcc/x86_64-pc-cygwin/7.4.0/cc1 main.c
 main
Analyzing compilation unit
Performing interprocedural optimizations
 <*free_lang_data> <visibility> <build_ssa_passes> <opt_local_passes> <targetclone> <free-inline-summary> <emutls> <whole-program> <inline>Assembling functions:
 <materialize-all-clones> <simdclone> main
Execution times (seconds)
 phase setup             :   0.00 ( 0%) usr   0.00 ( 0%) sys   0.00 (22%) wall    1184 kB (86%) ggc
 TOTAL                 :   0.00             0.00             0.01               1374 kB

$ ls
Makefile  help.c  help.h  main.c  main.s

$ /lib/gcc/x86_64-pc-cygwin/7.4.0/cc1 help.c
 herp
Analyzing compilation unit
Performing interprocedural optimizations
 <*free_lang_data> <visibility> <build_ssa_passes> <opt_local_passes> <targetclone> <free-inline-summary> <emutls> <whole-program> <inline>Assembling functions:
 <materialize-all-clones> <simdclone> herp
Execution times (seconds)
 phase setup             :   0.01 (100%) usr   0.00 ( 0%) sys   0.00 (33%) wall    1184 kB (86%) ggc
 TOTAL                 :   0.01             0.00             0.01               1370 kB

$ ls
Makefile  help.c  help.h  help.s  main.c  main.s

We now have two assembly files, main.s and help.s, which can be assembled into object files with the assembler as. But let's have a quick look at help.s:

$ cat help.s

        .file   "help.c"
        .text
        .globl  some_variable
        .data
        .align 4
some_variable:
        .long   1
        .text
        .globl  herp
        .def    herp;   .scl    2;      .type   32;     .endef
        .seh_proc       herp
herp:
        pushq   %rbp
        .seh_pushreg    %rbp
        movq    %rsp, %rbp
        .seh_setframe   %rbp, 0
        .seh_endprologue
        nop
        popq    %rbp
        ret
        .seh_endproc
        .ident  "GCC: (GNU) 7.4.0"

Even if we know nothing about assembler we can clearly identify the symbols some_variable and herp, which are assembly labels.

Ah yes, I forgot that I added a variable definition to help.c:

$ cat help.c

#include "help.h"
int some_variable = 1;
void herp() {}

We can assemble the assembly files with the assembler as:

$ as main.s -o main.o

$ ls
Makefile  help.c  help.h  help.s  main.c  main.o  main.s

$ as help.s -o help.o

$ ls
Makefile  help.c  help.h  help.o  help.s  main.c  main.o  main.s

Now we have two object files. We can see which symbols are exported ("extern") or needed ("undefined") with the utility nm("name mangling"):

$ nm --extern-only help.o

0000000000000000 T herp
0000000000000000 D some_variable

$ nm --extern-only main.o
                 U __main
                 U herp

"T" indicates that a symbol is in the "text" section, which contains code; "D" is the data section, and "U" stands for "undefined". (The undefined __main is a gcc and/or cygwin quirk.)

Here you have the source of your problem: Unless you pair your main.o with an object file that defines that undefined symbol, the linker cannot "resolve" the name and cannot produce the jump. There is no jump destination.

Now we can link the two object files to an executable. Cygwin requires us to link against the cygwin.dll; sorry for the circumstance.

$ ld main.o help.o /bin/cygwin1.dll -o main

$ ls
Makefile  help.c  help.h  help.o  help.s  main*  main.c  main.o  main.s

That's about it. I should add that the program doesn't run properly. It doesn't end, and doesn't react to Ctrl-C; I may be missing some Gnu or Windows build intricacies that gcc does for us.

Ah, Makefiles. Makefiles consist of target definitions and dependencies of these targets: A line

main: help.o main.o

specifies a target "main" depending on the two .o files.
Makefiles normally also contain rules specifying how to produce a target. But Make has built-in rules; it knows that you call the compiler to produce an .o file from a .c file (and it automatically considers this dependency), and it knows that you link the o files together to produce the target depending on them, provided the target has the same name as one of the .o files.

Therefore, we don't need any rules: We simply define the non-implicit dependencies. The entire Makefile for your project boils down to:

$ cat Makefile

CC=gcc
main: help.o main.o
help.o: help.h
main.o: help.h

CC=gcc specifies the C compiler to use. CC is a built-in make variable specifying the C compiler (CXX would specify the C++ compiler, e.g. g++).

Let's see:

$ make

gcc    -c -o main.o main.c
gcc    -c -o help.o help.c
gcc   main.o help.o   -o main
$ ls
Makefile  help.c  help.h  help.o  main.c  main.exe*  main.o

Do the dependencies work?

$ make
make: 'main' is up to date.

$ touch main.c

$ make
gcc    -c -o main.o main.c
gcc   main.o help.o   -o main

$ touch help.h

$ make
gcc    -c -o main.o main.c
gcc    -c -o help.o help.c
gcc   main.o help.o   -o main

That looks good: after touching a single source file make compiles only that file; but touching the header on which both files depend makes make compile both. The linking needs to be done in any case.

C标题问题:#include and quot“未定义的参考”

回梦 2025-02-18 13:33:59
  1. 关闭Eclipse
  2. 打开任务经理并杀死ADB.EXE
  3. 启动Eclipse
    它应该起作用。
  1. Close Eclipse
  2. Open Task Manager and kill adb.exe
  3. Start Eclipse
    It should work.

主机机器中的软件中止了建立的连接

回梦 2025-02-18 11:35:30

我在Boost Asio中的握手也有一些挑战。我在Filemaker插件中使用它,当涉及到这一行时:

namespace net = boost::asio;
..
..
stream.handshake(net::ssl::stream_base::handshake_type::client, ec);

因此,它崩溃了整个应用程序。
经过数小时,更改设置,谷歌搜索并阅读文档后,我将该方法放入了一个小的独立应用程序中,就像在孤立的环境中对其进行测试一样。在插件代码和测试应用程序中都具有所有相同的Boost版本(1.82.0)和相同的OpenSSL库(3.1.4)。

在测试应用程序中,它可以按预期工作。代码从服务器检索数据。在具有相同代码的插件中,FileMaker崩溃。

在您的下方,您可以查看崩溃日志片段以及测试应用程序的代码。

崩溃日志

Thread 0 Crashed::  Dispatch queue: com.apple.main-thread
0   FileMaker Pro Advanced                 0x10a6f7b64 boost::system::error_category::equivalent(boost::system::error_code const&, int) const + 4
1   ACF_plugin_db                          0x116ce2f4d boost::system::detail::failed_impl(int, boost::system::error_category const&) + 93 (error_category.hpp:217)
2   ACF_plugin_db                          0x116ce2ea5 boost::system::error_code::error_code(int, boost::system::error_category const&) + 53 (error_code.hpp:129)
3   ACF_plugin_db                          0x116ce2dd3 boost::system::error_code::error_code(int, boost::system::error_category const&) + 35 (error_code.hpp:130)
4   ACF_plugin_db                          0x116d0ee6d boost::asio::error::make_error_code(boost::asio::error::misc_errors) + 45 (error.hpp:354)
5   ACF_plugin_db                          0x116d11acf boost::system::error_code::error_code<boost::asio::error::misc_errors>(boost::asio::error::misc_errors, boost::system::detail::enable_if<(is_error_code_enum<boost::asio::error::misc_errors>::value) || (std::is_error_code_enum<boost::asio::error::misc_errors>::value), void>::type*) + 63 (error_code.hpp:150)
6   ACF_plugin_db                          0x116d11a83 boost::system::error_code::error_code<boost::asio::error::misc_errors>(boost::asio::error::misc_errors, boost::system::detail::enable_if<(is_error_code_enum<boost::asio::error::misc_errors>::value) || (std::is_error_code_enum<boost::asio::error::misc_errors>::value), void>::type*) + 35 (error_code.hpp:149)
7   ACF_plugin_db                          0x116d10612 boost::asio::ssl::detail::engine::map_error_code(boost::system::error_code&) const + 50 (engine.ipp:240)
8   ACF_plugin_db                          0x116d1024f unsigned long boost::asio::ssl::detail::io<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::ssl::detail::handshake_op>(boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>&, boost::asio::ssl::detail::stream_core&, boost::asio::ssl::detail::handshake_op const&, boost::system::error_code&) + 607 (io.hpp:81)
9   ACF_plugin_db                          0x116d0ffbc boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor> >::handshake(boost::asio::ssl::stream_base::handshake_type, boost::system::error_code&) + 76 (stream.hpp:437)
10  ACF_plugin_db                          0x116cdf364 boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor> >::handshake(boost::asio::ssl::stream_base::handshake_type) + 52 (stream.hpp:420)
11  ACF_plugin_db                          0x116cde1de SendSoapRequest(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) + 1710 (DocServiceXML.cpp:256)

测试应用程序的工作来源与插件相同的代码

//
//  main.cpp
//  test-boost-ssl
//
//  Created by Ole Kristian Ek Hornnes on 02/11/2023.
//

#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>

namespace net = boost::asio;
namespace ssl = boost::asio::ssl;
namespace http = boost::beast::http;
using tcp = boost::asio::ip::tcp;


struct httpResponse {
    int StatusCode;
    std::string ResultText;
};

httpResponse SendPostRequest(const std::string& xurl, const std::string& post_data) {
    net::io_context ioc;
    std::string url = xurl;
    // Determine the scheme (http or https), hostname, and path
    std::string scheme, hostname, path;
    int port = 0;
    httpResponse httpResult;
    
    if (url.substr(0, 5) == "https") {
        scheme = "https";
        port = 443;
        url = url.substr(8); // Remove "https://"
    } else if (url.substr(0, 4) == "http") {
        scheme = "http";
        port = 80;
        url = url.substr(7); // Remove "http://"
    }
    
    size_t slashPos = url.find('/');
    if (slashPos != std::string::npos) {
        hostname = url.substr(0, slashPos);
        path = url.substr(slashPos);
    } else {
        hostname = url;
        path = "/";
    }
    
    bool useSSL = (scheme == "https");
    
    // These objects perform I/O
    
    try {
        
        if ( useSSL ) {
            // Set up SSL context and stream
            // Set up SSL context (only if using SSL)
            
            net::io_context xxx;
            tcp::resolver resolver(xxx);
            // tcp::socket socket(ioc);
            net::ssl::context sslContext(net::ssl::context::tlsv12_client);
            // sslContext.set_options(net::ssl::context::default_workarounds);
            
      /*      sslContext.set_options(net::ssl::context::no_sslv2);
            sslContext.set_options(net::ssl::context::no_sslv3);
            sslContext.set_options(net::ssl::context::tlsv12);*/
            
            sslContext.set_default_verify_paths();
            net::ssl::stream<tcp::socket> stream = {xxx, sslContext };
      
            // Resolve the hostname and port
            auto it = resolver.resolve(hostname, std::to_string(port));
          // std::cout << "resolver " << std::string(it) << std::endl;
            boost::system::error_code ec;
           
            net::connect(stream.next_layer(), it, ec);
            
            if (ec) {
                std::stringstream err;
                err << "Error during SSL connect: " << ec << std::endl;
                httpResult.ResultText = err.str();
                httpResult.StatusCode = -2;
                return httpResult;
            }
            // stream.set_verify_mode(net::ssl::verify_peer);
            // Perform the SSL handshake
            
            try {
                stream.handshake(net::ssl::stream_base::handshake_type::client, ec);
            } catch (const std::exception &e)  {
                std::stringstream err;
                err << "Error during SSL handshake: " << e.what() << "ec: " << ec << std::endl;
                httpResult.ResultText = err.str();
                httpResult.StatusCode = -2;
                return httpResult;
            }
            
            if (ec) {
                std::stringstream err;
                err << "Error during SSL Handshake: " << ec << std::endl;
                httpResult.ResultText = err.str();
                httpResult.StatusCode = -3;
                return httpResult;
            }
            
            std::string agent ("ACF_Plugin for FileMaker ver. ");
            // agent += std::string (PLUGIN_VERSION);
            // Set up an HTTPS POST request
            http::request<http::string_body> req{http::verb::post, path, 11};
            req.set(http::field::host, hostname);
            req.set(http::field::user_agent, agent);
            req.set(http::field::content_type, "text/xml");
           //  req.set(http::field::soapaction, SoapAction);
            
            req.body() = post_data;
            req.prepare_payload();
            
            // Send the HTTP request
            http::write(stream, req);
            
            // This buffer is used for reading and must be persisted
            boost::beast::flat_buffer buffer;
            
            // Declare a container to hold the response
            http::response<http::string_body> res;
            
            // Receive the HTTP response
            http::read(stream, buffer, res);
            // Convert the response to a std::string and return it
            // Check the HTTP status code and set StatusCode accordingly
            httpResult.StatusCode = static_cast<int>(res.result_int());
            httpResult.ResultText = res.body();
            return httpResult;
        } else {
            tcp::socket socket(ioc);
            tcp::resolver resolver(ioc);
            // Resolve the hostname and port
            auto results = resolver.resolve(hostname, std::to_string(port));
            boost::asio::connect(socket, results.begin(), results.end());
            
            
            // Set up an HTTP POST request
            http::request<http::string_body> req{http::verb::post, path, 11};
            req.set(http::field::host, hostname);
            req.set(http::field::user_agent, "MyClient/1.0");
            req.set(http::field::content_type, "text/xml");
          /*  if (SoapAction != "" ) {
                req.set(http::field::soapaction, SoapAction);
            } */
            req.body() = post_data;
            req.prepare_payload();
            
            // Send the HTTP request
            http::write(socket, req);
            
            // This buffer is used for reading and must be persisted
            boost::beast::flat_buffer buffer;
            
            // Declare a container to hold the response
            http::response<http::string_body> res;
            
            // Receive the HTTP response
            http::read(socket, buffer, res);
            // Convert the response to a std::string and return it
            // Check the HTTP status code and set StatusCode accordingly
            httpResult.StatusCode = static_cast<int>(res.result_int());
            httpResult.ResultText = res.body();
            return httpResult;
        }
    } catch (const std::exception &e) {
        std::stringstream err;
        err << "Error: " << e.what() << std::endl;
        httpResult.ResultText = err.str();
        httpResult.StatusCode = -1;
        return httpResult;
    }
}

int main(int argc, char* argv[]) {
    
    std::string url;
    if (argc != 2) {
       // std::cerr << "Usage: postService <URL>" << std::endl;
       //  return 1;
        url = "https://myserver.no/wsx/doc/";
    } else {
        url = argv[1];
    }
    
    std::string post_data = "TEST\n\n"; // You can set your POST data here
    
    httpResponse result = SendPostRequest(url, post_data);
    
    std::cout << "URL: " << url << std::endl;
    std::cout << "HTTP Status Code: " << result.StatusCode << std::endl;
    std::cout << "Response Body:\n" << result.ResultText << std::endl;
    
    return 0;
}

在显示通信的测试时示例输出,我得到了肥皂失误,但是由于我没有't实际上发送了任何有效的肥皂请求,预期。但是,它表明功能与服务器交换数据。

URL: https://myserver.no/ws/doc/
HTTP Status Code: 500
Response Body:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Client</faultcode><faultstring>Bad Request</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>

Program ended with exit code: 0

I have also some challenge with this handshake in boost asio. I am using it in a FileMaker Plugin, and when it comes to this line:

namespace net = boost::asio;
..
..
stream.handshake(net::ssl::stream_base::handshake_type::client, ec);

It consequently crash the whole application.
After trying for hours, changing the setup, googling, and reading the documentation, I put the method into a small stand-alone application made like a command-line utility to test it in a isolated environment. Having all the same boost version (1.82.0) and the same openSSL libraries (3.1.4) in both the plugin code and test application.

In the test application, it works as expected. The code retrieve data from the server. In the plugin with the same code, FileMaker crash.

Below you ca see the crash log snippet, and also the code of the test application.

Crash log

Thread 0 Crashed::  Dispatch queue: com.apple.main-thread
0   FileMaker Pro Advanced                 0x10a6f7b64 boost::system::error_category::equivalent(boost::system::error_code const&, int) const + 4
1   ACF_plugin_db                          0x116ce2f4d boost::system::detail::failed_impl(int, boost::system::error_category const&) + 93 (error_category.hpp:217)
2   ACF_plugin_db                          0x116ce2ea5 boost::system::error_code::error_code(int, boost::system::error_category const&) + 53 (error_code.hpp:129)
3   ACF_plugin_db                          0x116ce2dd3 boost::system::error_code::error_code(int, boost::system::error_category const&) + 35 (error_code.hpp:130)
4   ACF_plugin_db                          0x116d0ee6d boost::asio::error::make_error_code(boost::asio::error::misc_errors) + 45 (error.hpp:354)
5   ACF_plugin_db                          0x116d11acf boost::system::error_code::error_code<boost::asio::error::misc_errors>(boost::asio::error::misc_errors, boost::system::detail::enable_if<(is_error_code_enum<boost::asio::error::misc_errors>::value) || (std::is_error_code_enum<boost::asio::error::misc_errors>::value), void>::type*) + 63 (error_code.hpp:150)
6   ACF_plugin_db                          0x116d11a83 boost::system::error_code::error_code<boost::asio::error::misc_errors>(boost::asio::error::misc_errors, boost::system::detail::enable_if<(is_error_code_enum<boost::asio::error::misc_errors>::value) || (std::is_error_code_enum<boost::asio::error::misc_errors>::value), void>::type*) + 35 (error_code.hpp:149)
7   ACF_plugin_db                          0x116d10612 boost::asio::ssl::detail::engine::map_error_code(boost::system::error_code&) const + 50 (engine.ipp:240)
8   ACF_plugin_db                          0x116d1024f unsigned long boost::asio::ssl::detail::io<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::ssl::detail::handshake_op>(boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>&, boost::asio::ssl::detail::stream_core&, boost::asio::ssl::detail::handshake_op const&, boost::system::error_code&) + 607 (io.hpp:81)
9   ACF_plugin_db                          0x116d0ffbc boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor> >::handshake(boost::asio::ssl::stream_base::handshake_type, boost::system::error_code&) + 76 (stream.hpp:437)
10  ACF_plugin_db                          0x116cdf364 boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor> >::handshake(boost::asio::ssl::stream_base::handshake_type) + 52 (stream.hpp:420)
11  ACF_plugin_db                          0x116cde1de SendSoapRequest(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) + 1710 (DocServiceXML.cpp:256)

The Working Source of the test application that has the same code as the plugin

//
//  main.cpp
//  test-boost-ssl
//
//  Created by Ole Kristian Ek Hornnes on 02/11/2023.
//

#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>

namespace net = boost::asio;
namespace ssl = boost::asio::ssl;
namespace http = boost::beast::http;
using tcp = boost::asio::ip::tcp;


struct httpResponse {
    int StatusCode;
    std::string ResultText;
};

httpResponse SendPostRequest(const std::string& xurl, const std::string& post_data) {
    net::io_context ioc;
    std::string url = xurl;
    // Determine the scheme (http or https), hostname, and path
    std::string scheme, hostname, path;
    int port = 0;
    httpResponse httpResult;
    
    if (url.substr(0, 5) == "https") {
        scheme = "https";
        port = 443;
        url = url.substr(8); // Remove "https://"
    } else if (url.substr(0, 4) == "http") {
        scheme = "http";
        port = 80;
        url = url.substr(7); // Remove "http://"
    }
    
    size_t slashPos = url.find('/');
    if (slashPos != std::string::npos) {
        hostname = url.substr(0, slashPos);
        path = url.substr(slashPos);
    } else {
        hostname = url;
        path = "/";
    }
    
    bool useSSL = (scheme == "https");
    
    // These objects perform I/O
    
    try {
        
        if ( useSSL ) {
            // Set up SSL context and stream
            // Set up SSL context (only if using SSL)
            
            net::io_context xxx;
            tcp::resolver resolver(xxx);
            // tcp::socket socket(ioc);
            net::ssl::context sslContext(net::ssl::context::tlsv12_client);
            // sslContext.set_options(net::ssl::context::default_workarounds);
            
      /*      sslContext.set_options(net::ssl::context::no_sslv2);
            sslContext.set_options(net::ssl::context::no_sslv3);
            sslContext.set_options(net::ssl::context::tlsv12);*/
            
            sslContext.set_default_verify_paths();
            net::ssl::stream<tcp::socket> stream = {xxx, sslContext };
      
            // Resolve the hostname and port
            auto it = resolver.resolve(hostname, std::to_string(port));
          // std::cout << "resolver " << std::string(it) << std::endl;
            boost::system::error_code ec;
           
            net::connect(stream.next_layer(), it, ec);
            
            if (ec) {
                std::stringstream err;
                err << "Error during SSL connect: " << ec << std::endl;
                httpResult.ResultText = err.str();
                httpResult.StatusCode = -2;
                return httpResult;
            }
            // stream.set_verify_mode(net::ssl::verify_peer);
            // Perform the SSL handshake
            
            try {
                stream.handshake(net::ssl::stream_base::handshake_type::client, ec);
            } catch (const std::exception &e)  {
                std::stringstream err;
                err << "Error during SSL handshake: " << e.what() << "ec: " << ec << std::endl;
                httpResult.ResultText = err.str();
                httpResult.StatusCode = -2;
                return httpResult;
            }
            
            if (ec) {
                std::stringstream err;
                err << "Error during SSL Handshake: " << ec << std::endl;
                httpResult.ResultText = err.str();
                httpResult.StatusCode = -3;
                return httpResult;
            }
            
            std::string agent ("ACF_Plugin for FileMaker ver. ");
            // agent += std::string (PLUGIN_VERSION);
            // Set up an HTTPS POST request
            http::request<http::string_body> req{http::verb::post, path, 11};
            req.set(http::field::host, hostname);
            req.set(http::field::user_agent, agent);
            req.set(http::field::content_type, "text/xml");
           //  req.set(http::field::soapaction, SoapAction);
            
            req.body() = post_data;
            req.prepare_payload();
            
            // Send the HTTP request
            http::write(stream, req);
            
            // This buffer is used for reading and must be persisted
            boost::beast::flat_buffer buffer;
            
            // Declare a container to hold the response
            http::response<http::string_body> res;
            
            // Receive the HTTP response
            http::read(stream, buffer, res);
            // Convert the response to a std::string and return it
            // Check the HTTP status code and set StatusCode accordingly
            httpResult.StatusCode = static_cast<int>(res.result_int());
            httpResult.ResultText = res.body();
            return httpResult;
        } else {
            tcp::socket socket(ioc);
            tcp::resolver resolver(ioc);
            // Resolve the hostname and port
            auto results = resolver.resolve(hostname, std::to_string(port));
            boost::asio::connect(socket, results.begin(), results.end());
            
            
            // Set up an HTTP POST request
            http::request<http::string_body> req{http::verb::post, path, 11};
            req.set(http::field::host, hostname);
            req.set(http::field::user_agent, "MyClient/1.0");
            req.set(http::field::content_type, "text/xml");
          /*  if (SoapAction != "" ) {
                req.set(http::field::soapaction, SoapAction);
            } */
            req.body() = post_data;
            req.prepare_payload();
            
            // Send the HTTP request
            http::write(socket, req);
            
            // This buffer is used for reading and must be persisted
            boost::beast::flat_buffer buffer;
            
            // Declare a container to hold the response
            http::response<http::string_body> res;
            
            // Receive the HTTP response
            http::read(socket, buffer, res);
            // Convert the response to a std::string and return it
            // Check the HTTP status code and set StatusCode accordingly
            httpResult.StatusCode = static_cast<int>(res.result_int());
            httpResult.ResultText = res.body();
            return httpResult;
        }
    } catch (const std::exception &e) {
        std::stringstream err;
        err << "Error: " << e.what() << std::endl;
        httpResult.ResultText = err.str();
        httpResult.StatusCode = -1;
        return httpResult;
    }
}

int main(int argc, char* argv[]) {
    
    std::string url;
    if (argc != 2) {
       // std::cerr << "Usage: postService <URL>" << std::endl;
       //  return 1;
        url = "https://myserver.no/wsx/doc/";
    } else {
        url = argv[1];
    }
    
    std::string post_data = "TEST\n\n"; // You can set your POST data here
    
    httpResponse result = SendPostRequest(url, post_data);
    
    std::cout << "URL: " << url << std::endl;
    std::cout << "HTTP Status Code: " << result.StatusCode << std::endl;
    std::cout << "Response Body:\n" << result.ResultText << std::endl;
    
    return 0;
}

Sample output when testing that shows communication, I got a soap-fault, but since I didn't actually send any valid soap request, its expected. However, it shows that the function exchange data with the server.

URL: https://myserver.no/ws/doc/
HTTP Status Code: 500
Response Body:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Client</faultcode><faultstring>Bad Request</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>

Program ended with exit code: 0

提升ASIO SSL握手故障

回梦 2025-02-17 21:05:42

您需要跟踪此处的最小数据将是用户最新操作和当前条纹计数的日期。

当用户执行条纹操作时,您需要检查最新操作的日期。如果最近的动作发生在不到一天之内,但现在已经是不同的一天,那么您就会增加条纹计数。如果超过两天,您将条纹计数重置为零;否则,您在检查条纹时会更新最新的动作时间戳

,则需要检查最新的动作时间戳。如果时间戳是最后一天的最后更新,则条纹数量是有效的,否则实际条纹计数确实为零。

另外,您只需简单地执行文档数据库,然后根据事务日志进行完整的条纹计算。对于长条纹用户来说,这将变得昂贵,尽管这将是最简单的实施。取决于您期望人们长期条纹的频率,这可能是可以接受的,也可能是不可接受的。

The smallest data you need to keep track of here is going to be the date of the most recent action by the user and the current streak count.

When the user done the streaked action, you need to check the date of the most recent action. If the most recent action happens within less than a day but now is already a different day, you increment the streak count; if it's further than two days, you reset the streak count to zero; otherwise you update the most recent action timestamp

When checking for streaks, you need to check for the most recent action timestamp as well. If the timestamp was last updated within the last day, the streak count is valid, otherwise the real streak count is really zero.

Alternatively, you can just simply do a document database and do the full streak calculations based on transaction logs. This will get expensive for long streak users, though it will be the simplest to implement. Depending on how often you expect people to have long streaks, this might or might not be acceptable.

我如何跟踪“条纹”在数据库中?

回梦 2025-02-17 01:35:17

尝试这样

   DELETE FROM 
    MyTable
    WHERE  
    
    Name like '%NULL%' OR  
    Name like '%Null%'  OR  
    Name like '%null%' 
     

Try like This

   DELETE FROM 
    MyTable
    WHERE  
    
    Name like '%NULL%' OR  
    Name like '%Null%'  OR  
    Name like '%null%' 
     

删除如果无匹配表中的条件-SQL Server中的条件

回梦 2025-02-16 22:54:06

当Python解释器导入软件包时,它在以下位置寻找包:

包含输入脚本(或当前目录)的目录。

pythonpath(目录名称的列表,具有与Shell变量路径相同的语法)。

依赖安装的默认值。

因此,如果您的软件包和脚本文件位于同一目录中,将很容易找到。但是显然您选择了另一个目录。然后,您必须使用文章中提到的方法来指定解释器的路径,例如修改 pythonpath 环境变量或使用sys.path.append() 方法。

这是另一种方法的建议。将您的软件包放在Python可以找到它的位置,例如lib文件夹。这样,您就不需要在每个文件开头使用sys.path.append()方法。

我正在使用虚拟环境

更新:

您可以使用虚拟环境。它不会有所作为。如果您担心某些因素并且不想使用它,那就没有问题了。只需在当前环境中找到lib文件夹,然后将包装放入其中即可。

例如(就我的计算机而言):

”在此处输入映像说明“

lib与此环境解释器相对应的文件夹在:

C:\Users\Admin\AppData\Local\Programs\Python\Python310\Lib

lib与此环境解释器相对应的文件夹在:

C:\Users\Admin\anaconda3\Lib

ps:也可以放置在site-packages 文件夹在lib文件夹下方的一个级别。

When the python interpreter is importing a package, it looks for the package in the following locations:

the directory containing the input script (or the current directory).

PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).

the installation-dependent default.

So if your package and script file are in the same directory, it will be easily found. But obviously you chose a different directory. Then you have to use the methods mentioned in your article to specify the path to the interpreter, such as modifying the PYTHONPATH environment variable or using the sys.path.append() method.

Here's a suggestion for another approach. Put your package where python can find it, say under the lib folder. This way you don't need to use the sys.path.append() method at the beginning of each file.

enter image description here

I am using a virtual environment

UPDATE:

You can use virtual environments. it won't make a difference. If you are worried about some factors and do not want to use it, there is no problem. Just find the lib folder in your current environment and put your package in it.

for example ( As far as my machine is concerned ) :

enter image description here

The lib folder corresponding to the interpreter of this environment is in:

C:\Users\Admin\AppData\Local\Programs\Python\Python310\Lib

enter image description here

The lib folder corresponding to the interpreter of this environment is in:

C:\Users\Admin\anaconda3\Lib

PS : It can also be placed in the site-packages folder one level below the lib folder.

VS代码在工作区中找不到自己的Python模块

回梦 2025-02-16 20:29:29

您可以使用match(),或find()。这是一个使用match()的示例

Sub Import_QTN_Data()

    Dim FileToOpen As Variant
    Dim OpenBook As Workbook, wsQuote As Worksheet, m
    
    Application.ScreenUpdating = False
    
    FileToOpen = Application.GetOpenFilename( _
                  Title:="Browse for your File & Import Range", _
                  FileFilter:="Excel Files (*.xls*),*xls*")
    If FileToOpen <> False Then
        Set wsQuote = ThisWorkbook.Worksheets("QUOTATION")
        Set OpenBook = Application.Workbooks.Open(FileToOpen)
        With OpenBook.Worksheets("QUOTATION")
            'use Match() on ColD
            m = Application.Match(.Range("T2").Value, wsQuote.Columns("D"), 0)
            If Not IsError(m) Then       'got a match (`m` is not an error value)
                .Range("U2:AH2").Copy
                wsQuote.Cells(m, "E").PasteSpecial xlPasteValues, skipblanks:=True
            End If
        End With
        OpenBook.Close False
    End If
    
    Application.ScreenUpdating = True

End Sub

You could use Match(), or Find(). Here's an example using Match()

Sub Import_QTN_Data()

    Dim FileToOpen As Variant
    Dim OpenBook As Workbook, wsQuote As Worksheet, m
    
    Application.ScreenUpdating = False
    
    FileToOpen = Application.GetOpenFilename( _
                  Title:="Browse for your File & Import Range", _
                  FileFilter:="Excel Files (*.xls*),*xls*")
    If FileToOpen <> False Then
        Set wsQuote = ThisWorkbook.Worksheets("QUOTATION")
        Set OpenBook = Application.Workbooks.Open(FileToOpen)
        With OpenBook.Worksheets("QUOTATION")
            'use Match() on ColD
            m = Application.Match(.Range("T2").Value, wsQuote.Columns("D"), 0)
            If Not IsError(m) Then       'got a match (`m` is not an error value)
                .Range("U2:AH2").Copy
                wsQuote.Cells(m, "E").PasteSpecial xlPasteValues, skipblanks:=True
            End If
        End With
        OpenBook.Close False
    End If
    
    Application.ScreenUpdating = True

End Sub

进口范围来自其他工作表

回梦 2025-02-16 13:15:21

您可以使用此修改后的正则:

(?<=await)([\S\s]*?)(?<!.+\.lean\(\))(;)

我所更改的只是:

负面外观。

制作\。精益逃脱括号背后的

You can use this modified regex:

(?<=await)([\S\s]*?)(?<!.+\.lean\(\))(;)

All I have changed is:

Making \.lean a negative look BEHIND

ESCAPING the parentheses.

正则:匹配两个字符串之间的文本,不包括我的字符串

回梦 2025-02-16 05:29:49

在典型的编译器实现中,您可以将代码视为“用Adress打印出 的代码”。另外,如果您将新功能调用添加到构成本地int的函数中,则很有可能a的值用来指向)更改。发生这种情况是因为堆栈将被包含不同数据的新帧覆盖。

但是,这是不确定的行为,您不应依靠它来工作!

In typical compiler implementations, you can think of the code as "print out the value of the memory block with adress that used to be occupied by a". Also, if you add a new function invocation to a function that constains a local int it's a good chance that the value of a (or the memory address that a used to point to) changes. This happens because the stack will be overwritten with a new frame containing different data.

However, this is undefined behaviour and you should not rely on it to work!

可以在其范围之外访问本地变量的内存吗?

更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文